c++ 为什么成员函数不能要求同一个类的静态constexpr成员为true?

jhkqcmku  于 2023-01-10  发布在  其他
关注(0)|答案(2)|浏览(124)

我试着让一个成员函数要求一个静态constexpr布尔成员为真。这对DRY一个相当复杂的需求很有帮助。我不知道编译器为什么不允许我这么做。
要求稍微简单的最小示例:

template <typename T>
struct Foo
{
    static constexpr bool isInt = std::integral<T>;
    void bar() requires (isInt);
    void goo() requires std::integral<T>;
};

template <typename T>
void Foo<T>::bar() requires (Foo<T>::isInt) // error: out-of-line definition of 'bar' does not match any declaration in 'Foo<T>' x86-64 clang 14.0.0 #1
{
    // ...
}

template <typename T>
void Foo<T>::goo() requires std::integral<T> // ok
{
    // ...
}

这是因为isInt是在同一个类中声明的吗?还是我有某种语法错误?

7hiiyaii

7hiiyaii1#

这里有一个问题,即类内声明和类外定义中的requires子句是否 * 等价 *(或 * 功能等价 *)。
但是,不管这个问题的答案是什么,最简单的解决方案就是使用完全相同的标记序列,这肯定是等价的:

template <typename T>
void Foo<T>::bar() requires (isInt)
{
    // ...
}

然而,当前的Clang版本不接受我试图命名静态成员的任何变体,尤其是那些在声明和定义中使用相同标记序列的变体。
但是在当前的Clang Backbone.js 上,所有的变化都是可以接受的,这表明这是一个最近修复的bug。

yptwkmov

yptwkmov2#

似乎是MSVC错误。解决方法如下:

#include <concepts>

template <class T>
concept isInt = std::integral<T>;

template <typename T>
struct Foo
{
    void bar() requires (isInt<T>);
};

template <typename T>
void Foo<T>::bar() requires (isInt<T>) 
{
}

https://godbolt.org/z/h6enoGqG6

相关问题