How does type inference work for string literals in C ++?

In C ++, if I have a generic function:

template <typename T> void func(T& s) { std::cout << "in generic\n"; std::cout << typeid(s).name(); } 

T will be output to typeid(s).name() .

But how come:

 func("test"); 

This general function works, but it doesn't:

 void func(const char*& s) { std::cout << "in overloaded\n"; std::cout << typeid(s).name(); } 

I know that it will work if I change const char*& to const char* or const char* const& in an overloaded function signature and that if I want to pass an argument to an overloaded function, it should not be temporary. I just don't understand what happened to T& , shouldn't it turn into const char*& after the output?

+5
source share
2 answers

String literals are arrays of const characters. Therefore, in the case of a template function called so:

 func("test"); 

T is inferred as char const[5] . And s is a reference to a string literal, and its type is char const (&)[5] . That is, a reference to an array of 5 const char.

+4
source

Type "test" is const char[5] . When a function template is called and an argument is used to output a parameter of a reference type, conversion between arrays and pointers does not occur. Thus, the general function outputs T as const char[5] - you can see that the output for "test" and for const char* is different:

 template<typename T> void func(T& s){ std::cout << "in generic\n"; std::cout << typeid(s).name() << '\n'; } int main() { func("test"); const char *c = "test"; func(c); } 

GCC Output:

 in generic A5_c in generic PKc 

On the other hand, in a nonequivalent function, you want to refer to a pointer that is not a constant, to const char . However, since the type "test" is const char[5] , it must undergo the transformation of the matrix into a pointer, which means that the resulting const char* is temporary (rvalue). Therefore, it cannot communicate with reference to non-constant.

+4
source

Source: https://habr.com/ru/post/1204802/


All Articles