SFINAE 内部概念模板参数

SFINAE inside concept template argument

本文关键字:参数 内部 SFINAE      更新时间:2023-10-16

SFINAE在概念参数中工作吗?(也许这里不叫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?

海湾合作委员会似乎没有它的行为:https://godbolt.org/z/SEH94-

SFINAE 仍然使用约束。

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

[温度结构原子]

3 要确定是否满足原子约束,请 参数映射和模板参数首先替换为 它的表达。如果替换导致无效类型或 表达式,则不满足约束。否则, 必要时进行左值到右值的转换,E 应 布尔类型的常量表达式。满足约束,如果和 仅当 E 的求值结果为 true 时。如果,在 程序,对于相同的原子,满意结果是不同的 约束和模板参数,程序格式不正确,否 需要诊断。[ 示例:

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的行为是正确的。