Как предотвратить создание неспециализированных шаблонов?
У меня есть шаблонный class
(назовите его Foo
), который имеет несколько специальностей. Я хотел бы, чтобы компиляция завершилась неудачей, если кто-то попытается использовать неспециализированную версию Foo
.
Вот что я на самом деле имею:
template class Foo { Foo() { cannot_instantiate_an_unspecialized_Foo(); } // This method is NEVER defined to prevent linking. // Its name was chosen to provide a clear explanation why the compilation failed. void cannot_instantiate_an_unspecialized_Foo(); }; template class Foo { }; template class Foo { };
Так что:
- Что такое неопределенный контекст?
- Каков любопытно повторяющийся шаблон шаблона (CRTP)?
- std :: function vs template
- Расшифровка сообщений об ошибках шаблона C ++
- объявление друга объявляет функцию без шаблона
int main() { Foo foo; }
Работает, пока:
int main() { Foo foo; }
Не.
Очевидно, что цепочка компилятора только жалуется, когда происходит процесс связывания. Но есть ли способ заставить его жаловаться раньше?
Я могу использовать boost
.
- Вывод типа параметра шаблона c ++
- Получить индекс типа элемента кортежа?
- Дизайн шаблонов веб-приложений
- Можно ли написать шаблон для проверки существования функции?
- Лямбда-выражения как параметры шаблона classа
- Определить, является ли тип указателем в функции шаблона
- Как использовать class в Java?
- Вывод первого аргумента шаблона с другими параметрами шаблона по умолчанию
Просто не определяйте class:
template class Foo; template <> class Foo { }; int main(int argc, char *argv[]) { Foo f; // Fine, Foo exists Foo fc; // Error, incomplete type return 0; }
Почему это работает? Просто потому, что нет никакого общего шаблона. Объявлено, да, но не определено.
Вы просто не можете определить базовый случай:
template class Foo; // no definition! template <> class Foo { /* ... */ }; // Foo is OK
Трюк для C ++ 0x (также доступен с эмуляцией static_assert
C ++ 03, но сообщение об ошибке не обязательно лучше, чем оставить основной шаблон неопределенным):
template struct dependent_false: std::false_type {}; template struct Foo { static_assert( dependent_false::value , "Only specializations of Foo may be used" ); };
Утверждение будет действовать только тогда, когда Foo
создается с помощью первичного шаблона. Использование static_assert( false, ... )
будет постоянно вызывать утверждение.