隐式类型转换编译失败,这是为什么?
Implicit type conversion failed to compile, why is that?
我写了一个小代码:
#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
无法编译,即使我在 s3
.
上使用 decay<char*>
也是如此
不同之处在于我是否为 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;
}
还是失败了
为什么?
因为template type argument deduction不考虑隐式转换。
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
对于第二种情况,编译器无法将 M<T>
与 const char [6]
匹配,函数模板在重载解析之前被忽略。
第三种情况失败,因为"Hello"
(即const char [6]
)无法转换为decay<char *>
。您的意思可能是 typename decay<char*>::type
,但由于与第二种情况相同的原因,它仍然无法编译。
我写了一个小代码:
#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
无法编译,即使我在 s3
.
decay<char*>
也是如此
不同之处在于我是否为 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;
}
还是失败了
为什么?
因为template type argument deduction不考虑隐式转换。
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
对于第二种情况,编译器无法将 M<T>
与 const char [6]
匹配,函数模板在重载解析之前被忽略。
第三种情况失败,因为"Hello"
(即const char [6]
)无法转换为decay<char *>
。您的意思可能是 typename decay<char*>::type
,但由于与第二种情况相同的原因,它仍然无法编译。