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)。
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;
概念定义是任意的布尔表达式,所以这就足够了并且 运行 不违反任何规则。
我在 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)。
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;
概念定义是任意的布尔表达式,所以这就足够了并且 运行 不违反任何规则。