关于C ++ 0x引用崩溃的问题

时间:2010-12-13 01:28:29

标签: c++ c++11

我不知道为什么这些代码无法编译。我在Visual c + + 2010和gcc中测试了-std = c ++ 0x。有人提出一些建议吗? 谢谢!

template<typename T>
class Foo
{
public:
 void test(const T&){cout<<"const";}
 void test(      T&){cout<<"non const";}
};

int main()
{
 int a;
 Foo<int&> f;
}

编译错误:'void Foo :: test(T)':已定义或声明的成员函数

但为什么要编译?

template<typename T> void foo(const T&){cout<<"const"; }
template<typename T> void foo( T&){cout<<"non const"; }
int main()
 {
    int a; 
    foo<int&>(a);
 }

我读过c ++ 0x文章说:T&amp; &安培; == T&安培;所以const T&amp; &安培; == const T&amp; ?

3 个答案:

答案 0 :(得分:13)

  

我读过c ++ 0x文章说:T&amp; &安培; == T&安培;所以const T&amp; &安培; == const T&amp; ?

实际上,这并没有多大意义。恕我直言,最好将其放入表格中:

T       T&      const T      const T&
---------------------------------------
int     int&    const int    const int&
int&    int&    int&         int&
        (1)     (2)          (1+2)

1: Reference collapsing in action
2: const applies to the reference and is therefore ignored

如果T已经是引用(第2行),则const T中的const适用于引用而不适用​​于裁判。但是,在初始化之后你无法让它引用另一个对象的意义上,引用本质上是不变的,所以在这里忽略const。你可以把它想象成“const崩溃”。 ; - )

答案 1 :(得分:8)

此:

Foo<int&> f;

引发了这种实例化:

class Foo<int&>
{
public:
 void test(int&);
 void test(int&);
};

const应用于作为参考的类型是无操作。将它与在参考数据成员上运行的非静态成员函数进行比较:

struct A {
  int &ref;

  // valid: const member function doesn't treat "ref" as "const int&". 
  void operate() const {
    ref = 0;
  }
};

您必须将int传递给Foo<...>才能实现目标。

答案 2 :(得分:1)

对于第二个问题,两个实例化的函数具有相同的参数类型,并且都是模板(如果一个是模板,另一个是非模板函数,重载决策将选择后一个),所以重载决策将选择更专业的模板。通常const T&amp;是一种比T&amp;更专业的类型,所以第一个模板函数被调用。