Шаблонная (или нет) функция, которую можно вызвать только один раз

128
09 марта 2018, 15:22

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

// Module1.cpp
void Module1::initModule()
{
   ...
   registerType<AAA>(Factory1());
   registerType<BBB>([this]() { return this->createBBB();});
   ...
}
// Module2.cpp
void Module2::initModule()
{
   ...
   registerType<CCC>([]() { return CCCImpl(); });
   registerType<AAA>(Factory2()); // <- Вот тут на линковке(?) должно сломаться
   ...
}

UPD: Уточнение. Типы AAA, BBB, CCC это интерфейсы и определены заранее и не обязательно в том модуле где вызывается регистрация. В момент регистрации registerType(...) мы по факту передаем правильно сконфигурированную фабрику.

Answer 1

Чтобы "сломалось" на линковке нужно создать в модуле extern (и не weak) символ.

К сожалению, сделать это внутри функции не получится (точнее, я не знаю, как это сделать).

Наверное, проще всего объявить о своих намерениях вне функции, используя макрос, который раскроется в код функции.

Она может реально ниоткуда и не вызываться, хотя для контроля целостности можно (например, тоже макросом) сгенерить код, вызывающий эту функцию внутри вашей registerType<>.

Макрос может быть примерно таким:

#define USE_REGISTER(name) const char * f_ ## name () { return #name; }

Вы вставляете его в свой файл по одному разу для каждого регистрируемого где-то далее типа.

READ ALSO
C++. std::vector - не пойму, SFML. куча вопросов

C++. std::vector - не пойму, SFML. куча вопросов

Проясните пожалуйстаТо что кладется в std::vector оно размещается в динамической памяти (то есть как при вызове new)? Как вообще поместить объекты...

145
Является ли нуль-терминатор байтом? [дубликат]

Является ли нуль-терминатор байтом? [дубликат]

На данный вопрос уже ответили:

122
Ошибка. Проблема в коде или в среде?

Ошибка. Проблема в коде или в среде?

Ошибка: maincpp|10|error: expected ')' before 'st'

132
C++ std::string::find неверно работает

C++ std::string::find неверно работает

Нужно распарсить строку, для этого необходимо найти позицию знака

129