What is the exact type of "" when outputting `auto`?

In this line:

auto a = "Hello World"; 

What is exact type a ? I would suggest char[] or const char* const , but I'm not sure.

+4
source share
3 answers

N4296 2.13.5 / 8

UTF-8 plain string literals and string literals are also indicated as narrow string literals. The narrow string literal is of type "array n const char" , where n is the size of the string, as defined below, and has a static storage duration (3.7).

But since the variable is initialized, as in your code, it is actually const char* , you can check it like this.

 template<typename> struct TD; int main() { auto a = "Hello World"; TD<decltype(a)> _; } 

An error will be compiled here in which you can see the actual type of the TD instance, something like this with clang

 error: implicit instantiation of undefined template 'TD<const char *>' 

N4296 7.1.6.4

If the placeholder is an automatic type specifier, the type being inferred is determined using the rules for deriving template arguments.

 template<typename> struct TD; template<typename T> void f(T) { TD<T> _; } int main() { auto c = "Hello"; TD<decltype(c)> _; f("Hello"); } 

Both instances of an object of type TD are of type TD<const char*> .

N4926 14.8.2.1

The output of the template argument is made by comparing each function with the type of the template template (call it P) with the type of the corresponding call argument (call it A), as described below.

If P is not a reference type:

If A is an array type, the pointer type created by the standard transformation using the pointer matrix (4.2) is used instead of A for the output type

+10
source

If you have no reason to think that this will be an implementation or not defined, you can simply check:

 #include <iostream> template <typename T> void f() { std::cout << "other\n"; } template <> void f<const char*>() { std::cout << "const char*\n"; } template <> void f<const char* const>() { std::cout << "const char* const\n"; } template <> void f<const char(&)[12]>() { std::cout << "const char[12]\n"; } int main() { auto a = "Hello World"; f<decltype(a)>(); } 

Output:

 const char* 

Verifying that compiling ++a is another key (it does), and although the implementation defined by #include <typeinfo> / typeid(a).name() can often answer such questions.

Change to auto& a and you will see a change to const char(&)[12] .

+2
source

You can print a type using typeinfo

 int main() { auto a = "Hello World"; std::cout << "type is: " << typeid(a).name() << '\n'; } 

on gcc it will print

pi: PKc

which denotes a pointer to a char constant. If you are on Windows, the output will be much more readable, but you will also get used to this syntax.

If you know more or less the type you need, you can also check if two types are equivalent:

 #include <typeinfo> std::cout << std::is_same<const char*, decltype(a)>::value << std::endl; 
+1
source

All Articles