I wrote a small code:
#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;
}
Well the first s1 successfully compiles, although if I change M::M to explicit, it will also fail. But s2 and s3 fail to compile, even when I use decay<char*> on s3.
The difference is whether I specified template initialization argument type for f or not. Why do s2 and s3 fail to compile, any principles behind this in the C++ standard?
If I change main function to like this:
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;
}
It still fails.
Why?
s2case, given the function parameter beingconst char[6]the compiler can conclude that the template parameter must bechar. P.S. Your decay is wrong.const char[6]decays toconst char *, and notchar *.