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

问题描述 投票:3回答:1

我写了一个小代码:

#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;
}

它仍然失败。

为什么?

c++ string templates implicit
1个回答
3
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.