auto with string literals

2020-02-09 07:03发布

#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]

2条回答
在下西门庆
2楼-- · 2020-02-09 07:26

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.

查看更多
爷、活的狠高调
3楼-- · 2020-02-09 07:30

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) ...

查看更多
登录 后发表回答