SFINAE内部概念模板参数

时间:2020-05-17 06:07:53

标签: c++ sfinae c++20 c++-concepts

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

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?

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-

1 个答案:

答案 0 :(得分:1)

SFINAE仍然可以在约束条件下工作。

替换失败会导致原子约束(例如(!std::same_as<std::invoke_result_t<F, int>, void>))被视为不满足

[temp.constr.atomic]

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

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

—结束示例]

在模板自变量推导过程中,未满足的约束导致推导过程不成功

[扣除温度]

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

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

[温度超过]

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

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