requires constraint must evaluate to bool. so no SFINAE

守給你的承諾、 提交于 2019-12-11 06:03:43

问题


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

it says

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

and

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

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 ?


回答1:


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

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

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>);

or type (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>);

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

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


来源:https://stackoverflow.com/questions/53493715/requires-constraint-must-evaluate-to-bool-so-no-sfinae

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!