Search code examples
c++overloadingstandardsstring-literals

Why does clang take a string literal as a pointer rather than an array?


#include <iostream>
using namespace std;

void f(const char* arg)
{
    cout << "arg is a pointer" << endl;
}

template<size_t N>
void f(const char (&arg)[N])
{
    cout << "arg is an array." << endl;
}

int main()
{
    f("");
}

My compiler is clang 3.8.

The output is:

arg is a pointer

However, according to cppreference.com,

The type of an unprefixed string literal is const char[].

Why does the overload resolution not behave as expected?


Solution

  • It does behave as expected, you just need to adjust your expectations ;-)

    const char[1] and const char (&)[1] are different types.

    The conversions to const char* (array-to-pointer conversion) and const (&char)[1] (identity conversion) are both considered exact matches, but a non-template is a better match than a template.

    If you write a non-template size-specific overload,

    void f(const char (&arg)[1])
    

    you will get an error that the function call is ambiguous.