Концепции C++ и специализация шаблонов; как получить удобную ошибку компилятора
У меня есть два (или более) шаблона, каждый из которых может адаптировать определенный набор классов, определенных концепцией. Чтобы два шаблона могли иметь одно и то же имя, они должны быть специализациями.
template< typename T >
struct pin_in { static_assert( always_false<T>::value, . . . ); };
template< is_pin_in T >
struct pin_in< T > . . .
template< is_pin_in_out T >
struct pin_in< T > . . .
это работает нормально, когда одна из специализаций совпадает. Когда нет ни одного подходящего шаблона базы, и я получаю ошибку. Механизм работает. Я люблю концепции!
но сообщение об ошибке, которое я получаю (GCC 7.2.0), указывает на утверждение. могу я как-то сделать базовый шаблон не выбран, чтобы я получил сообщение об ошибке, которое говорит, что ни один шаблон не соответствует классу аргументов?
2 ответов
Ура, я нашел решение! Вам нужно, чтобы основной шаблон был ограничен:
template <class T>
requires is_pin_in<T> || is_pin_in_out<T>
struct pin_in {};
template <is_pin_in T>
struct pin_in<T> {};
template <is_pin_in_out T>
struct pin_in<T> {};
и вы получаете хорошее диагностическое сообщение:
<source>: In function 'auto test()': 29 : <source>:29:16: error: template constraint failure pin_in<char> a; ^ 29 : <source>:29:16: note: constraints not satisfied 7 : <source>:7:24: note: within 'template<class T> concept const bool is_pin_in<T> [with T = char]' constexpr concept bool is_pin_in = std::is_same_v<T, int>; ^~~~~~~~~ 7 : <source>:7:24: note: 'std::is_same_v' evaluated to false 9 : <source>:9:24: note: within 'template<class T> concept const bool is_pin_in_out<T> [with T = char]' constexpr concept bool is_pin_in_out = std::is_same_v<T, unsigned>; ^~~~~~~~~~~~~ 9 : <source>:9:24: note: 'std::is_same_v' evaluated to false Compiler exited with result code 1
ну, мое сообщение с некоторыми фиктивными ограничениями, но вы получаете точку
попробуйте использовать std:: enable_if для удаления базового шаблона из разрешения перегрузки. Что-то вроде этого:--2-->
template< typename T >
struct pin_in<typename std::enable_if<false>::type> {};
template< is_pin_in T >
struct pin_in<typename std::enable_if<true>::type>< T > . . .
template< is_pin_in_out T >
struct pin_in<typename std::enable_if<true>::type>< T > . . .