隐式类型转换无法编译,为什么会这样?

时间:2016-06-29 01:42:21

标签: c++ string templates implicit

我写了一个小代码:

#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更改为显式,它也会失败。但s2s3无法编译,即使我在decay<char*>上使用s3

区别在于我是否为f指定了模板初始化参数类型。为什么s2s3无法编译,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;
}

它仍然失败。

为什么?

1 个答案:

答案 0 :(得分:3)

因为template type argument deduction不考虑隐式转化。

  

类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后会发生。

对于第二种情况,编译器无法将M<T>const char [6]匹配,在重载解析之前只会忽略函数模板。

第三种情况失败,因为"Hello"(即const char [6])无法转换为decay<char *>。你的意思可能是typename decay<char*>::type,但由于第二种情况的原因,它仍然无法编译。