默认与推导的模板参数?

Vin*_*ent 2 c++ templates standards-compliance c++11 template-argument-deduction

在下面的 :

template<typename Type>
struct MyClass
{
    template<typename OtherType> MyClass(const MyClass<OtherType>& x);
    template<typename OtherType = Type> void test(const MyClass<OtherType>& x);
};
Run Code Online (Sandbox Code Playgroud)

在函数中,test之间做了什么:

情况1:默认参数优先级:隐式调用转换构造函数MyClass<Type>(const MyClass<OtherType>& x)并被MyClass<Type>::test<Type>(const MyClass<Type>& x)调用。

情况2:推导出的参数是priority:MyClass<Type>::test<Type>(const MyClass<OtherType>& x)被调用。


我认为最好的答案是第二个,但我不确定。您能否向我确认这一点(并且这种情况已由标准明确定义)?


编辑:测试函数由以下方式调用:

MyClass<double> d;
MyClass<unsigned int> ui;
d.test(ui); // <- So the question is : is ui implicitely 
            //    converted to MyClass<double> or not ?
Run Code Online (Sandbox Code Playgroud)

jog*_*pan 5

test将被称为

\n\n
MyClass<double>::test(const MyClass<unsigned int> &)\n
Run Code Online (Sandbox Code Playgroud)\n\n

即不会有uifromMyClass<unsigned int>到的转换MyClass<double>

\n\n

默认模板参数永远不会覆盖给定的模板参数。仅当未给出模板参数并且编译器无法从函数参数中推断出它时才使用它。

\n\n

来自 C++11 标准:

\n\n
\n

(\xc2\xa714.8.2/5) 替换和调整后的函数类型用作模板参数推导的函数模板类型。如果尚未推导模板参数,则使用其默认模板参数(如果有)。[ 例子:

\n\n
template <class T, class U = double>\nvoid f(T t = 0, U u = 0);\nvoid g() {\n  f(1, \xe2\x80\x99c\xe2\x80\x99);      // f<int,char>(1,\xe2\x80\x99c\xe2\x80\x99)\n  f(1);           // f<int,double>(1,0)\n  f();            // error: T cannot be deduced\n  f<int>();       // f<int,double>(0,0)\n  f<int,char>();  // f<int,char>(0,0)\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94 结束示例]

\n
\n