使用额外的不可推导的模板参数重载函数是否有效?
Is it valid to overload function with extra non-deducible template parameter?
以下代码编译并适用于 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);
除了第二个函数中的额外 Xs
参数外,有两个 fn
函数具有相同的声明。
我想确定这是标准接受的,而不是这些编译器额外提供的东西?由于所有 3 个都这样做,我想这将是标准的,但你永远不会知道。
我还想知道我关于为什么 work/would 成为标准的假设是否正确:
- 在调用
fn(x1)
中,无法推导出Xs
所以fn
的第二个重载被轻轻丢弃(SFINAE?)?
- 在调用
fn<Xs>(x1)
中,第一个重载将是 fn(X<X<int>>)
,它与参数 x1
不匹配,因此第一个重载也被丢弃?
There are two fn
functions with identical declarations except for the extra Xs
parameter in the second one.
没关系,您可以使用不同的参数或不同的模板参数重载函数模板。
- in the call
fn(x1)
, Xs
cannot be deduced so the second overload of fn
is discarded gently (SFINAE?)?
是的,除了它不是 SFINAE,而是重载解析。 SFINAE 中的 S 代表替换。当无法推导模板参数时,不会发生替换。
在[temp.over]/1中有描述:
... For each function template, if the argument deduction and checking succeeds, the template-arguments (deduced and/or explicit) are used to synthesize the declaration of a single function template specialization which is added to the candidate functions set to be used in overload resolution.
关于第二个项目符号(fn<X<double>>(x1)
),两个模板都可以合成一个有效的声明,但是X<int>
不能转换为X<X<double>>
,所以选择了第二个重载作为唯一可行的。
注意:当多个模板重载可行时,执行partial ordering以确定最专业的模板。
以下代码编译并适用于 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);
除了第二个函数中的额外 Xs
参数外,有两个 fn
函数具有相同的声明。
我想确定这是标准接受的,而不是这些编译器额外提供的东西?由于所有 3 个都这样做,我想这将是标准的,但你永远不会知道。
我还想知道我关于为什么 work/would 成为标准的假设是否正确:
- 在调用
fn(x1)
中,无法推导出Xs
所以fn
的第二个重载被轻轻丢弃(SFINAE?)? - 在调用
fn<Xs>(x1)
中,第一个重载将是fn(X<X<int>>)
,它与参数x1
不匹配,因此第一个重载也被丢弃?
There are two
fn
functions with identical declarations except for the extraXs
parameter in the second one.
没关系,您可以使用不同的参数或不同的模板参数重载函数模板。
- in the call
fn(x1)
,Xs
cannot be deduced so the second overload offn
is discarded gently (SFINAE?)?
是的,除了它不是 SFINAE,而是重载解析。 SFINAE 中的 S 代表替换。当无法推导模板参数时,不会发生替换。
在[temp.over]/1中有描述:
... For each function template, if the argument deduction and checking succeeds, the template-arguments (deduced and/or explicit) are used to synthesize the declaration of a single function template specialization which is added to the candidate functions set to be used in overload resolution.
关于第二个项目符号(fn<X<double>>(x1)
),两个模板都可以合成一个有效的声明,但是X<int>
不能转换为X<X<double>>
,所以选择了第二个重载作为唯一可行的。
注意:当多个模板重载可行时,执行partial ordering以确定最专业的模板。