Концепции 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 > . . .