本文介绍了SFINAE内部概念模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SFINEE是否在概念参数内起作用?(也许这里不叫SFINAE).示例:

Does SFINAE work inside a concept argument? (maybe it's not called SFINAE here). Example:

template <class F>
    requires
        std::invocable<F, int> && // <-- is this needed?
        (!std::same_as<std::invoke_result_t<F, int>, void>)
auto foo(F f, int a) -> int

是否需要上述 std :: invocable< F,int> ?

如果我们这样忽略它:

template <class F>
    requires (!std::same_as<std::invoke_result_t<F, int>, void>)
auto foo(F f, int a) -> int

即使 std :: invoke_result_t< F,int> 不是(即,如果无法调用)此版本格式是否正确?还是UB/格式不正确,ndr?

Is this version well-formed even if std::invoke_result_t<F, int> is not (i.e. if it is not invocable) or is it UB/ill formed, ndr?

foo(11, 24);
// std::invoke_result_t<int, int> does not exist,
// is the second variant the one without `std::invocable<F, int>` ok in this case?


gcc似乎没有它就会表现: https://godbolt.org/z/SEH94-

推荐答案

SFINAE仍可在约束条件下使用.

SFINAE still works with constraints.

替换失败会导致认为原子约束(例如(!std :: same_as< std :: invoke_result_t< F,int> ;, void>))

A substitution failure results in an atomic constraint (such as (!std::same_as<std::invoke_result_t<F, int>, void>)) being deemed as not satisfied

3 要确定是否满足原子约束,这首先将参数映射和模板参数替换为它的表达.如果替换导致无效的类型,或者表达式,不满足约束条件.否则,如有必要,执行左值到右值转换,并且E为bool类型的常量表达式.如果且满足约束仅当对E的评估结果为true时.如果在不同点程序,对于相同的原子,满意度结果是不同的约束和模板参数,程序格式错误,否需要诊断.[示例:

3 To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression. If substitution results in an invalid type or expression, the constraint is not satisfied. Otherwise, the lvalue-to-rvalue conversion is performed if necessary, and E shall be a constant expression of type bool. The constraint is satisfied if and only if evaluation of E results in true. If, at different points in the program, the satisfaction result is different for identical atomic constraints and template arguments, the program is ill-formed, no diagnostic required. [ Example:

template<typename T> concept C =
  sizeof(T) == 4 && !true;      // requires atomic constraints sizeof(T) == 4 and !true

template<typename T> struct S {
  constexpr operator bool() const { return true; }
};

template<typename T> requires (S<T>{})
void f(T);                      // #1
void f(int);                    // #2

void g() {
  f(0);                         // error: expression S<int>{} does not have type bool
}                               // while checking satisfaction of deduced arguments of #1;
                                // call is ill-formed even though #2 is a better match

—结束示例]

在模板参数推导过程中,不满意的约束导致推导过程不成功

During template argument deduction, an unsatisfied constraint causes the deduction process to be unsuccessful

5 ...如果函数模板具有关联的约束([temp.constr.decl]),检查这些约束是否满足要求([temp.constr.constr]).如果不满足约束条件,请键入推论失败.

5 ... If the function template has associated constraints ([temp.constr.decl]), those constraints are checked for satisfaction ([temp.constr.constr]). If the constraints are not satisfied, type deduction fails.

古老的SFINAE规范在重载解析期间仍然适用,因此当替换失败时,将不考虑重载.

The age old SFINAE specification still applies during overload resolution, so when substitution fails, the overload is not considered.

1 ...如果对于给定的功能模板,论证推论失败否则综合功能模板的专业化将是格式不正确,则不会将此功能添加到候选集该模板的功能...

1 ... If, for a given function template, argument deduction fails or the synthesized function template specialization would be ill-formed, no such function is added to the set of candidate functions for that template ...

总而言之,GCC的行为符合人们的预期.

So all in all, GCC behaves correctly, as one should expect.

这篇关于SFINAE内部概念模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 05:46