【问题标题】:function template overloading: const* vs. const&函数模板重载:const* 与 const
【发布时间】:2013-05-15 14:50:17
【问题描述】:

当我有两个这样的模板化函数重载时:

template<class T>
void foo( T const& )
{
    // do something with a const reference
    cout << "const reference version";
}

template<class T>
void foo( T const* )
{
    // do something with a const pointer
    cout << "const pointer version";
}

为什么编译器在用非常量指针类型实例化时会选择第一个版本?

int* bar;
foo( bar ); // prints "const reference version"

char const* baz;
foo( baz ); // prints "const pointer version"

【问题讨论】:

标签: c++ templates overloading


【解决方案1】:

原因是因为bar是一个非常量指针,所以int* const&amp;实际上是比int const*更好的匹配,因为它不必在指针类型上加上const

如果barconst 合格,那么它将与T const* 版本完全匹配。

【讨论】:

    【解决方案2】:
    #include <iostream>
    using namespace std;
    void foo(int const&) {
        cout << "const reference" << endl;
    }
    
    void foo(int const*) {
        cout << "const pointer" << endl;
    }
    
    int main() {
        int *hi;
        foo (hi);   //const pointer
        foo((*hi)); //const reference
        foo(&(*hi));//const pointer
    }
    

    这里的处理是引用和指针是不同的。指针是一种唯一类型,其中对值的引用与值本身没有什么不同,或者更确切地说,是对象的别名。所以比如上面这个版本的代码是不会编译的。

    #include <iostream>
    using namespace std;
    void foo(int const&) {
        cout << "const reference" << endl;
    }
    
    void foo(int) {
        cout << "hi there" << endl;
    }
    
    int main() {
        int hi;
        foo(hi); //const reference
    }
    

    因为 foo 的声明是模棱两可的。编译器无法在它们之间做出决定。

    【讨论】:

      【解决方案3】:

      您可以使用typeid 确定您的模板类型发生了什么。

      #include <iostream>
      #include <typeinfo>
      using namespace std;
      
      template<class T> void foo( T const& ) {
          cout << "const reference version T="<< typeid(T).name()<<endl;
      }
      
      template<class T> void foo( T const* ) {
          cout << "const pointer version T="<<typeid(T).name()<<endl;
      }
      
      int main() {
          int* i_ptr=0;
          foo(i_ptr);
      
          const int* ci_ptr=0;
          foo(ci_ptr);    
      }
      

      这个输出(注意确切的输出取决于你的编译器)

      const reference version T=Pi
      const pointer version T=i
      

      这表明在第一种情况下T = int* 和完整的参数类型是int* const&amp;,在第二种情况下T=int 和完整的参数类型是int const *

      【讨论】:

        【解决方案4】:

        template&lt;class T&gt; void foo( T const* ) 需要 T 上的 const 指针。好吧,如果它是您拥有的唯一声明,那么当您尝试将非 const 指针作为参数传递时,将会出现编译错误。

        使用template&lt;class T&gt; void foo( T const&amp; ),推断出T 的类型是int*,它是通过引用函数给出的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多