【发布时间】:2021-10-12 22:38:59
【问题描述】:
以下代码可以编译并与 gcc (9)、clang (11) 和 msvc (16.28) 一起正常工作:
template <class A>
struct X {
A a;
constexpr X(A a) : a{a} { }
};
template <class A>
constexpr auto fn(X<A> const& x) {
return X<A>(x.a - 1);
}
template <class Xs, class A>
constexpr auto fn(X<A> const& x) {
return Xs(x.a - 1);
}
constexpr X<int> x1{3};
constexpr auto x2 = fn(x1);
constexpr auto x3 = fn<X<double>>(x1);
有两个 fn 函数具有相同的声明,除了第二个中的额外 Xs 参数。
我想确定这是标准接受的,而不是这些编译器额外提供的东西?由于所有 3 个都这样做,我猜这将是标准的,但你永远不知道。
我还想知道我对为什么这项工作/将成为标准的假设是否正确:
- 在调用
fn(x1)中,Xs无法推断出,所以fn的第二个重载被轻轻丢弃(SFINAE?)? - 在调用
fn<Xs>(x1)中,第一个重载将是fn(X<X<int>>),它与参数x1不匹配,因此第一个重载也被丢弃?
【问题讨论】:
-
大多数情况下,拒绝第二次重载的不是 SFINAE,因为甚至没有替换。
标签: c++ templates language-lawyer