C++ 概念,如何检查 constexpr static int 是否等于 1,或类似的...? Clang 不同意 GCC 和 MSVC

C++ Concept, how to check a constexpr static int is equal to 1, or similar...? Clang disagrees with GCC and MSVC

我在 cpprefference 上找不到与 static constexpr 成员的 匹配的概念的正确语法。此代码在 GCC 和 MSVC 上编译和运行正常,但在 Clang 中不起作用。我想知道是否有人知道这是我的错误,还是 GCC 和 MSVC 或 Clang 的问题? 这是一个 godbolt 三个编译器都打开的,我认为它说明了这一点!

#include <concepts>
#include <iostream>

template<typename T>
concept MyConcept = requires (T t){
    requires t.member == 1;

    //[clang's error]
    // note: because 't.member == 1' would be invalid: 
    //       constraint variable 't' cannot be used in an evaluated context
};

struct S {
    constexpr static int member {2};
};
struct D {
    constexpr static int member {1};
};

template<MyConcept T>
void func(){
    std::cout << "matched\n";
}

int main(){
    func<D>();
    return 0;
}

这里的 Clang 是正确的(谢谢,Casey)。

[expr.prim.req.nested]/2 说:

A local parameter shall only appear as an unevaluated operand within the constraint-expression.

并且[expr.ref]/1说:

A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template, and then followed by an id-expression, is a postfix expression. The postfix expression before the dot or arrow is evaluated;55 the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.

t.member 中,计算 t,我们不允许在这种情况下这样做。

另一种表达方式是完全删除 requirement-body 并直接检查静态成员:

template<typename T>
concept MyConcept = T::member == 1;

概念定义是任意的布尔表达式,所以这就足够了并且 运行 不违反任何规则。