要求约束必须评估为布尔。所以没有SFINAE [英] requires constraint must evaluate to bool. so no SFINAE

查看:79
本文介绍了要求约束必须评估为布尔。所以没有SFINAE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对原子约束一章很好奇, https:// en。 cppreference.com/w/cpp/language/constraints

I'm curious about the chapter "atomic constraints" https://en.cppreference.com/w/cpp/language/constraints


取代后的E的类型必须完全是bool。不允许转换

The type of E after substitution must be exactly bool. No conversion is permitted

f(0); // error: S<int>{} does not have type bool when checking #1,
          // even though #2 is a better match

哎呀。这意味着在使用require子句时没有 SFINAE机制吗?是不是让您感到不高兴

因为我可以看到某些模板类型在经过表达式后如何导致布尔值,而其他情况则没有。现在,我们需要使用 enable_if 和其他东西。

ouch. which means there is no SFINAE mecanism when working with require clauses ? Isn't it a bummer ?
Because I can see how some template types can result in bool after going through the expression, but not others. And now we're back needing to use enable_if and stuff. pain much ?

推荐答案

此限制的目的是使出错的难度加大,从而导致概念无法令人满意或始终令人满意,例如:

The intent of this restriction is to make it harder to make errors that result in unsatisfiable or always-satisfied concepts, for example:

template<class T> concept C1 = sizeof(T); // Oops, I meant to write sizeof(T) >= 2

如果 sizeof(T)被隐式转换为 bool C 将满足所有完整的对象类型。实际上,如果您真正想要的是,可以简单地将表达式强制转换为 bool

If sizeof(T) were to implicitly convert to bool, C would satisfied by all complete object types. In practice, you can simply forcibly convert an expression to bool if that's what you really want:

template<class T> concept C2 = (bool)sizeof(T); // I did *not* mean to write sizeof(T) >= 2

注意替换产生无效表达式时,我们不满意( https://godbolt.org/z/xMHoJ0 ):

Note that concepts are unsatisfied when substitution produces an invalid expression (https://godbolt.org/z/xMHoJ0):

template<class T> concept C3 = (bool)T::value;
static_assert(C3<std::true_type>);
static_assert(!C3<int>);

或键入( https://godbolt.org/z/tnreG0 ):

template<class T> concept C4 = C3<typename T::type>;
static_assert(C4<std::is_same<int, int>>);
static_assert(!C4<int>);

所以要求子句不做SFINAE!

so "requires-clauses don't do SFINAE!" doesn't precisely characterize the situation.

我想我应该指出另一个潜在的难题-原子约束表达式必须是常量表达式。如果替换为约束表达式会产生非常数表达式,则程序的格式不正确( https:// godbolt。 org / z / LQA1XQ ):

I suppose I should point out the other potential gotcha - atomic constraint expressions must be constant expressions. If substitution into a constraint expression produces a non-constant expression, the program is ill-formed (https://godbolt.org/z/LQA1XQ):

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

这篇关于要求约束必须评估为布尔。所以没有SFINAE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆