C++ 要求约束必须计算为bool。所以没有SFINAE

C++ 要求约束必须计算为bool。所以没有SFINAE,c++,c++-concepts,c++20,C++,C++ Concepts,C++20,我对原子约束这一章很好奇 上面说 替换后的E类型必须完全为布尔。不转换 允许 及 哎哟。这意味着在处理require子句时没有SFINAE-mecanism?这不是一件令人沮丧的事吗? 因为我可以看到一些模板类型在遍历表达式后如何生成bool,而其他模板类型则不然。现在我们回来了,需要使用enable_if之类的东西。痛吗?此限制的目的是使错误更难导致无法满足或始终满足的概念,例如: template<class T> concept C1 = sizeof(T); // Oops,

我对原子约束这一章很好奇

上面说

替换后的E类型必须完全为布尔。不转换 允许

哎哟。这意味着在处理require子句时没有SFINAE-mecanism?这不是一件令人沮丧的事吗?
因为我可以看到一些模板类型在遍历表达式后如何生成bool,而其他模板类型则不然。现在我们回来了,需要使用enable_if之类的东西。痛吗?

此限制的目的是使错误更难导致无法满足或始终满足的概念,例如:

template<class T> concept C1 = sizeof(T); // Oops, I meant to write sizeof(T) >= 2
请注意,当替换生成无效表达式时,概念是不满足的:

或类型:

所以要求条款不适用于SFINAE!并不能准确描述这种情况

我想我应该指出其他潜在的gotcha-原子约束表达式必须是常量表达式。如果替换到约束表达式中会产生一个非常量表达式,则程序的格式不正确:


此限制的目的是使错误更难导致无法满足或始终满足的概念,例如:

template<class T> concept C1 = sizeof(T); // Oops, I meant to write sizeof(T) >= 2
请注意,当替换生成无效表达式时,概念是不满足的:

或类型:

所以要求条款不适用于SFINAE!并不能准确描述这种情况

我想我应该指出其他潜在的gotcha-原子约束表达式必须是常量表达式。如果替换到约束表达式中会产生一个非常量表达式,则程序的格式不正确:


首先,std::enable_if is SFINAE。@ThomasLang Well yes。如果需要替换不是本机SFINAE,则必须使用enable_明确地进行替换,如果这是问题所在。对于初学者来说,std::enable_if是SFINAE。@ThomasLang Well是的。如果需要替换不是本机SFINAE,您必须使用enable_明确地进行替换,如果这是问题所在。多亏了您,我明白了我的误解。有三种类型的失败,只要我们尊重显式constexpr bool形式,我们就有一种形式的SFINAE。美好的多亏了你,我才明白我误解了什么。有三种类型的失败,只要我们尊重显式constexpr bool形式,我们就有一种形式的SFINAE。美好的
template<class T> concept C2 = (bool)sizeof(T); // I did *not* mean to write sizeof(T) >= 2
template<class T> concept C3 = (bool)T::value;
static_assert(C3<std::true_type>);
static_assert(!C3<int>);
template<class T> concept C4 = C3<typename T::type>;
static_assert(C4<std::is_same<int, int>>);
static_assert(!C4<int>);
template<class T> concept C5 = T::f();

struct S1 {
    static constexpr bool f() { return true; }
};

struct S2 {
    static constexpr bool f() { return false; }
};

struct S3 {
    static bool f() { return true; }
};

static_assert(!C5<void>); // Invalid expression: SFINAE and concept is not satisfied
static_assert(!C5<int>);  // Ditto

static_assert(C5<S1>);  // Constant expression that evaluates to true
static_assert(!C5<S2>); // Constant expression that evaluates to false

static_assert(C5<S3>);  // Ill-formed: not a constant expression