Overload not considered even though it looks like a better match

Viewed 61

This is rejected by both gcc (live on godbolt) and clang:

#include <string>

namespace
{
    std::string
    to_string(char const (&str) [14])
    { return str; }
}

void f()
{
    using std::to_string;
    char const hello[14] = "Hello, World!";
    (void) to_string(hello);
}

The compiler considers each of the std::to_string overloads and conclude with:

error: no matching function for call to 'to_string(const char [14])'

If I remove using std::to_string, my overload is considered and called. Why? How to fix it (other than removing the using)?

2 Answers

The scope of the using declaration matters. It's a proper declaration, so name hiding takes effect. Inside the function the global scope version isn't visible. You need to reintroduce it:

using ::to_string;
using std::to_string;

This using declaration

using std::to_string;

hides the declaration in the global namespace. So the compiler does not see the function ::to_string.

So you have to write

using std::to_string;
using ::to_string;

And make the unnamed namespace inline.

inline namespace
{
    // ...
}
Related