C++ 特殊约束需要什么?
假设我正在编写一个类模板,其中一些成员受类型模板参数static constexpr data member的存在和值的约束:C++ 特殊约束需要什么?,c++,compiler-errors,language-lawyer,c++20,c++-concepts,C++,Compiler Errors,Language Lawyer,C++20,C++ Concepts,假设我正在编写一个类模板,其中一些成员受类型模板参数static constexpr data member的存在和值的约束: template<class T> struct A { constexpr bool operator()() requires T::value { return T::value; } constexpr bool operator()() { return false; } }; #include <type_traits>
template<class T>
struct A {
constexpr bool operator()() requires T::value { return T::value; }
constexpr bool operator()() { return false; }
};
#include <type_traits>
static_assert(A<std::true_type>()());
static_assert(!A<std::false_type>()());
static_assert(!A<void>()());
模板
结构A{
constexpr bool运算符()()需要T::value{返回T::value;}
constexpr bool运算符(){return false;}
};
#包括
静态断言(A()());
静态断言(!A());
静态断言(!A());
MSVC和gcc接受这一点,但clang拒绝,除非Irequires T::value
withrequires{requires T::value;}
。这是一个叮当作响的bug,还是其他编译器松懈;C++需要需求所需的情况吗?标准怎么说
相关的(嗯,⅔ 至少):这是一个叮当作响的bug(已提交)
看起来,clang正在将void
替换为T::value
,并判定因为这是一个无效的表达式,所以约束无效。但规则是:
为了确定是否满足原子约束,首先将参数映射和模板参数替换到其表达式中。如果替换导致无效类型或表达式,则不满足约束
在这种情况下,替换会导致无效的类型或表达式,因此其结果应该是不满足约束
请注意,此重载:
constexpr bool操作符()()需要T::value{return T::value;}
仅当T::value
是有效的表达式且计算结果为true
时,才有效。这就相当于:
constexpr bool操作符()()需要T::value{return true;}
在这种情况下,这很好,因为在另一种情况下,您返回的是false
,因此没有理由区分T::value
存在,但是false
与T::value
不存在
但我认为无论如何都值得澄清。啊,是的,我可能把这个例子简化了。有了(很多)上下文,它就更有意义了。