我正在玩弄concepts,我试图定义一个concept可以接受任何值non-type parameter的函数,然后函数会使用关键字后跟the 来isUnsignedInt检查参数是否为an 。unsigned intrequiredconcept
问题是,我可以传递一个负整数,并且没有错误消息,类型不是unsigned int。
我对概念的理解错了吗?
目前,我正在使用gcc 9.2 compiler和我的CMake contains add_compile_options(-fconcepts),它启用了concepts。
码:
template<auto a>
concept special = requires(){
{a} -> unsigned int;
};
template<auto a> requires special<a>
constexpr auto isUnsignedInt(){
return a;
}
int main(){
std::cout << isUnsignedInt<-2>() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
-2
Run Code Online (Sandbox Code Playgroud)
这个:
Run Code Online (Sandbox Code Playgroud){a} -> unsigned int;
C ++ 20将获得的概念版本不再是一回事。依所有权利,这应该是编译错误。但是由于该更改最多仅在几个月前才进行,因此可以在您的编译器下编译也就不足为奇了。
由于它不再是有效的语法,所以真正的问题是它以前的含义。这也解释了为什么他们将其删除。
该语法并不意味着“此表达式是确切的类型unsigned int”。这意味着“此表达式可隐式转换为类型unsigned int”。显然int可以隐式转换为unsigned int,这就是为什么该概念通过负数的原因。
您希望它表示“相同”的事实,尽管事实并非如此,这恰恰是删除它的原因。因此,您必须明确地将其拼写出来:{a} -> std::same_as<unsigned int>,在哪里std::same_as等价于trait的概念std::is_same_v。由于GCC可能尚未包含标准库概念,因此您必须编写自己的等效库。