В C ++, как объявить структуру данных в заголовочном файле, в то время как она определена в исходном файле? - PullRequest
0 голосов
/ 27 апреля 2018

Скажем, я хочу использовать typedef, чтобы определить новый набор MyTypeSet с настроенными функциями хеширования и компаратора в исходном файле. Я хочу скрыть все детали реализации в исходном файле.

typedef std::unordered_set<MyType, MyTypeHash, MyTypeKeyEqual>
MyTypeSet;

Затем я хочу объявить MyTypeSet в заголовочном файле для использования другими модулями. Но я не хочу выставлять MyTypeHash и MyTypeKeyEqual

Просто не могу понять правильный синтаксис.

1 Ответ

0 голосов
/ 27 апреля 2018

Этого нельзя сделать с typedef. Пользователь MyTypeSet должен иметь возможность видеть полные определения для MyType, MyTypeHash и MyTypeKeyEqual, чтобы знать, как скомпилировать MyTypeSet.

Существует несколько подходов, используемых для разграничения открытого интерфейса шаблонного кода от деталей реализации:

  • Поместите детали реализации в другой заголовок («MyTypeImpl.hpp»), который включен в публичный заголовок.
  • Поместите частные типы реализации в пространство имен с именами detail, private или аналогичное.
  • Менять частные имена символами подчеркивания, как в MyTypeHash_. (Это хорошо видно в стандартной библиотеке MSVC).

Если абсолютно необходимо хранить MyTypeHash и MyTypeKeyEqual в секрете, тогда можно объявить MyTypeSet как класс, который имеет только методы, необходимые конечному пользователю. Тогда MyTypeSet может использовать идиому pImpl , чтобы иметь std::unordered_set в качестве переменной-члена, видимой только в исходном файле. Все методы MyTypeSet будут реализованы путем вызова std::unordered_set.

Такой MyTypeSet не может иметь точно такой же открытый интерфейс, как std::unordered_set, потому что std::unordered_set предоставляет свои типы хешей и ключей в качестве типов элементов.

...