c++概念和模板专门化;如何获得用户友好的编译错误

时间:2022-11-24 23:38:37

I have two (or more) templates that can each adapt a specific set of classes, identified by a concept. To make it possible for the two templates to have the same name, they must be specializations.

我有两个(或更多)模板,每个模板都可以适应一组特定的类,由一个概念标识。为了使两个模板具有相同的名称成为可能,它们必须是专门化。

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 > . . .

This works OK when one of the specializations match. When none match the base template is selected, and I get the assertion failure. The mechanism works. I love concepts!

当其中一个专门化匹配时,这是可以工作的。当没有匹配的基础模板被选中时,我得到断言失败。的工作机制。我爱概念!

But the error message I get (GCC 7.2.0) points to the assertion. Can I somehow make the base template not be selected, so I would get an error message that tells that no template matched the argument class?

但是我得到的错误消息(GCC 7.2.0)指向这个断言。我是否可以不选择基模板,这样就会得到一个错误消息,告诉我没有模板匹配这个参数类?

2 个解决方案

#1


2  

Hurray, I found a solution! What you need is to have the main template constrained:

我找到解决办法了!您需要的是对主模板进行约束:

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> {};

And you get a good diagnostic message:

你会得到一个很好的诊断信息:

<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

well, my message is with some dummy constraints, but you get the point

我的信息是有一些伪约束的,但是你懂的

#2


0  

Try to use std::enable_if to remove the base template from overload resolution. Something like this:

尝试使用std: enable_if从重载解析中删除基本模板。是这样的:

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 > . . .

#1


2  

Hurray, I found a solution! What you need is to have the main template constrained:

我找到解决办法了!您需要的是对主模板进行约束:

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> {};

And you get a good diagnostic message:

你会得到一个很好的诊断信息:

<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

well, my message is with some dummy constraints, but you get the point

我的信息是有一些伪约束的,但是你懂的

#2


0  

Try to use std::enable_if to remove the base template from overload resolution. Something like this:

尝试使用std: enable_if从重载解析中删除基本模板。是这样的:

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 > . . .