Search code examples
c++arrayspointersoverload-resolution

How can you make sure that a function with array-to-pointer conversion loses in overload resolution?


I want to be able to differentiate array from pointers in overload resolution :

class string {
public:
        string(const char* c_str);

        template<int N>
        string(const char (&str) [N]);
};


int main() {
        const char* c_str = "foo";
        string foo(c_str);      // ok will call string(const char*)

        string bar("bar");      // call string(const char*) instead of the array version
}

The best I have found so far is to use a reference to the pointer instead of a pointer :

class string {
public:
        string(const char*& c_str);

        template<int N>
        string(const char (&str) [N]);
};


int main() {
        const char* c_str = "foo";
        string foo(c_str);      // ok will call string(const char*)
        string bar("bar");      // ok, will call the array version
}

it's not exactly the same thing and I want to know if a better way exist


Solution

  • You need to make the first overload a poorer choice when both are viable. Currently they are a tie on conversion ranking (both are "Exact Match"), and then the tie is broken because non-templates are preferred.

    This ought to make the conversion ranking worse:

    struct stg
    {
        struct cvt { const char* p; cvt(const char* p_p) : p(p_p) {} };
    
        // matches const char*, but disfavored in overload ranking
        stg(cvt c_str); // use c_str.p inside :(  Or add an implicit conversion
    
        template<int N>
        stg(const char (&str) [N]);
    };