代码之家  ›  专栏  ›  技术社区  ›  paercebal

const char*和const char(&p)[t_size]之间的最佳查找匹配

  •  2
  • paercebal  · 技术社区  · 14 年前

    我有两个功能:

    void foo(const char * p)
    

    template<size_t T_Size>
    void foo(const char (& p)[T_Size]) ;
    

    给出呼叫:

    int main(int argc, char* argv[])
    {
       char a[21] ;                          // typeid : A21_c
       sprintf(a, "a[21] : Hello World") ;
    
       const char * b = "b : Hello World" ;  // typeid : PKc
    
       // note that literal "liter. : Hello World" has a typeid : A21_c
    
       foo(a) ;                      // calls foo(const char (& p)[T_Size])
       foo(b) ;                      // calls foo(const char * p)
       foo("liter. : Hello World") ; // calls foo(const char * p) ???
    
       return 0 ;
    }
    

    显然,打电话来 foo 当调用 字面上写着“升”。“Hello World”没有,尽管两个具有相同的类型(根据RTTI)。

    符号查找所遵循的规则是什么,以选择一个重载而不是另一个重载?

    为什么声明的数组和字符串文字之间的行为不同?

    谢谢!

    编辑

    请注意,一种获得所需结果的方法(即,让一个小小的字符串与 foo(const char (& p)[T_Size]) 功能)是移除 void foo(const char *p) 并添加:

    struct FooIndirect
    {
        const char * m_p ;
        FooIndirect(const char *p) : m_p(p) {}
    } ;
    
    void foo(const FooIndirect & p)
    {
        // do something with p.m_p
    }
    

    这种间接性使得模板foo更好地匹配字符串litterals,并且仍然允许用户使用指针(间接性将在优化编译模式下被删除)。

    我在我的G++4.4.3上测试过它,但我相信它在每个编译器上都会以同样的方式工作。

    2 回复  |  直到 11 年前
        1
  •  4
  •   Chubsdad    14 年前

    表9在标准第13章(过载分辨率)中,将“数组到指针”转换(对于非模板)排序为与“不需要转换”(对于模板版本)相同的排序(完全匹配)。

    其他一切都一样,非模板版本优先于模板版本。

        2
  •  1
  •   Puppy    14 年前

    如果与模板化函数相比,编译器将始终调用非模板化重载(如果可用)。您提供了一个完全足够的非模板化重载,因此编译器调用它。