C ++,概念不能将无符号整数用作结果类型?

M.M*_*Mac 5 c++ c++-concepts

我正在玩弄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)

Nic*_*las 9

这个:

{a} -> unsigned int;
Run Code Online (Sandbox Code Playgroud)

C ++ 20将获得的概念版本不再是一回事。依所有权利,这应该是编译错误。但是由于该更改最多仅在几个月前才进行,因此可以在您的编译器下编译也就不足为奇了。

由于它不再是有效的语法,所以真正的问题是它以前的含义。这也解释了为什么他们将其删除。

该语法并不意味着“此表达式是确切的类型unsigned int”。这意味着“此表达式可隐式转换为类型unsigned int”。显然int可以隐式转换为unsigned int,这就是为什么该概念通过负数的原因。

您希望它表示“相同”的事实,尽管事实并非如此,这恰恰是删除它的原因。因此,您必须明确地将其拼写出来:{a} -> std::same_as<unsigned int>,在哪里std::same_as等价于trait的概念std::is_same_v。由于GCC可能尚未包含标准库概念,因此您必须编写自己的等效库。