隐式类型转换编译失败,这是为什么?

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 更改为显式,它也会失败。但是 s2s3 无法编译,即使我在 s3.

上使用 decay<char*> 也是如此

不同之处在于我是否为 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;
}

还是失败了

为什么?

因为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,但由于与第二种情况相同的原因,它仍然无法编译。