我写了一个小代码:
#include<type_traits>
using namespace std;
template<typename T>
struct M{
/*explicit*/ M(const T*) {}
};
template<typename T>
M<T> f(const M<T>&) {return M<T>();}
int main() {
M<char> s1 = f<char>("Hello"); // OK
M<char> s2 = f("Hello"); // error
M<char> s3 = f(decay<char*>("Hello")); // error
return 0;
}
第一个s1
成功编译,但如果我将M::M
更改为显式,它也会失败。但s2
和s3
无法编译,即使我在decay<char*>
上使用s3
。
区别在于我是否为f
指定了模板初始化参数类型。为什么s2
和s3
无法编译,C ++标准中的任何原理?
如果我将main函数改为这样:
int main()
{
M<char> s1=f<char>("Hello");//OK
const char* p="hello";
M<char> s2=f(p);//error
M<char> s3=f(decay<const char*>("Hello"));//error
return 0;
}
它仍然失败。
为什么?
答案 0 :(得分:3)
因为template type argument deduction不考虑隐式转化。
类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后会发生。
对于第二种情况,编译器无法将M<T>
与const char [6]
匹配,在重载解析之前只会忽略函数模板。
第三种情况失败,因为"Hello"
(即const char [6]
)无法转换为decay<char *>
。你的意思可能是typename decay<char*>::type
,但由于第二种情况的原因,它仍然无法编译。