C++ 特殊约束需要什么?

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>

假设我正在编写一个类模板,其中一些成员受类型模板参数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>
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拒绝,除非I
requires T::value
with
requires{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
不存在


但我认为无论如何都值得澄清。

啊,是的,我可能把这个例子简化了。有了(很多)上下文,它就更有意义了。