array decay to pointer and overload resolution

前端 未结 3 888
余生分开走
余生分开走 2020-12-03 15:12

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

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

        template&         


        
相关标签:
3条回答
  • 2020-12-03 15:45

    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]);
    };
    
    0 讨论(0)
  • 2020-12-03 15:48

    A more generic version of this problem could be detected as follows.

    template <class T>
    void func(T, 
              typename std::enable_if<std::is_pointer<T>::value, void>::type * = 0)
    {
      // catch ptr
    }
    
    template <class T, int N>
    void func(T (&)[N])
    {
      //catch array
    }
    
    int main(void)
    {
      int arr[5];
      char *b = 0;
      func(arr); // catch array
      func(b);   // catch ptr
    }
    
    0 讨论(0)
  • 2020-12-03 16:10

    You can use SFINAE. This might not be the best way, but it should work ok:

    //thanks to dyp for further reduction
    template<typename T, typename = typename std::enable_if<std::is_same<T, char>::value>::type>
    string(const T * const &) {std::cout << "const char *\n";}
    
    template<std::size_t N> //credit to jrok for noticing the unnecessary SFINAE
    string(const char(&)[N]) {std::cout << "const char(&)[" << N << "]\n";}
    

    Here's a live example.

    0 讨论(0)
提交回复
热议问题