2016-06-29 6 views
2

я написал небольшой код:Неявное преобразование типов не удалось скомпилировать, почему?

#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++?

Если изменить основную функцию нравится:

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

Попробуйте поставить себя в обувь компилятора. Объясните, как в случае 's2', если параметр функции является' const char [6], компилятор может заключить, что параметр шаблона должен быть 'char'. Постскриптум Ваш распад неправильный. 'const char [6]' распадается на 'const char *', а не 'char *'. –

ответ

2

Потому что template type argument deduction не рассматривает неявные преобразования.

Тип вывода не учитывает неявные преобразования (кроме перечисленных выше настроек): это задание для разрешения перегрузки, которое происходит позже.

Для 2-го случая, компилятор может не совпадать с M<T>const char [6], шаблон функции просто игнорируется, прежде чем разрешение перегрузки.

Третий случай не работает, потому что "Hello" (т. Е. const char [6]) не может быть преобразован в decay<char *>. Вы могли бы означать typename decay<char*>::type, но он по-прежнему не будет компилироваться по той же причине, что и в случае с 2-м корпусом.

+0

Если «T» означает любой тип, почему M не может соответствовать T «const char [6]»? –

+0

@HindForsum 'T' может совпадать, но тип параметра -' M ', который не может совпадать. – songyuanyao

Смежные вопросы