问题
#include <iostream>
#include <typeinfo>
int main()
{
const char a[] = "hello world";
const char * p = "hello world";
auto x = "hello world";
if (typeid(x) == typeid(a))
std::cout << "It's an array!\n";
else if (typeid(x) == typeid(p))
std::cout << "It's a pointer!\n"; // this is printed
else
std::cout << "It's Superman!\n";
}
Why is x
deduced to be a pointer when string literals are actually arrays?
A narrow string literal has type "array of n
const char
" [2.14.5 String Literals [lex.string] §8]
回答1:
The feature auto
is based on template argument deduction and template argument deduction behaves the same, specifically according to §14.8.2.1/2 (C++11 standard):
- If P is not a reference type
- If A is an array type, the pointer type produced by the array-to-pointer conversion is used in place of A for type deduction
If you want the type of the expression x
to be an array type, just add &
after auto
:
auto& x = "Hello world!";
Then, the auto
placeholder will be deduced to be const char[13]
. This is also similar to function templates taking a reference as parameter. Just to avoid any confusion: The declared type of x will be reference-to-array.
回答2:
Why is x deduced to be a pointer when string literals are actually arrays?
Because of array-to-pointer conversion.
If x
is to be deduced as array, only if the following is allowed:
const char m[] = "ABC";
const char n[sizeof(m)] = m; //error
In C++, an arrray cannot be initialized with another array (like above). In such cases, the source array decays into pointer type, and you're allowed to do this instead:
const char* n = m; //ok
The rules for type-inference with auto
is same as the rules of type-deduction in function template:
template<typename T>
void f(T n);
f(m); //T is deduced as const char*
f("ABC"); //T is deduced as const char*
auto n = m; //n's type is inferred as const char*
auto n = "ABC"; //n's type is inferred as const char*
§7.1.6.4/6 says about auto
specifier:
The type deduced for the variable d is then the deduced A determined using the rules of template argument deduction from a function call (14.8.2.1) ...
来源:https://stackoverflow.com/questions/12016757/auto-with-string-literals