Неявное преобразование типов не удалось скомпилировать, почему так?
Я написал небольшой код:
#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;
}
Это все еще не удается.
Зачем? Спасибо за любую помощь.
1 ответ
Потому что при выводе аргументов типа шаблона не учитываются неявные преобразования.
Вывод типа не учитывает неявные преобразования (кроме корректировок типа, перечисленных выше): это работа по разрешению перегрузки, которая происходит позже.
Во втором случае компилятор не может соответствовать M<T>
с const char [6]
, шаблон функции просто игнорируется перед разрешением перегрузки.
3-й случай терпит неудачу, потому что "Hello"
(т.е. const char [6]
) не может быть преобразован в decay<char *>
, Вы могли бы иметь в виду typename decay<char*>::type
, но он все равно не скомпилируется по той же причине, что и во втором случае.