开发者

Question about C++0x reference collapse

开发者 https://www.devze.com 2023-01-30 10:15 出处:网络
I don\'t know why these code can\'t be compiled.I\'v tested in Visual c++ 2010 and gcc with -std=c++0x. anyone give some suggestion?

I don't know why these code can't be compiled. I'v tested in Visual c++ 2010 and gcc with -std=c++0x. anyone give some suggestion? thanks!

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;
}

开发者_如何学Ccompile error: 'void Foo::test(T)' : member function already defined or declared

but why this can be compiled?

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);
 }

i'v read c++0x article said: T& & ==T& , so const T& & == const T& ?


i'v read c++0x article said: T& & ==T& , so const T& & == const T& ?

Actually, that doesn't make a lot of sense. IMHO, it's better to put this into a table:

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

If T is already a reference (2nd row) the const in const T applies to the reference and not to the referee. But a reference is inherently constant in the sense that you cannot make it refer to another object after initialization, so a const is just ignored here. You can think of it as "const collapsing". ;-)


This:

Foo<int&> f;

gives rise to this instantiation:

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

const applied to a type that is a reference is a no-op. Compare it with a non-static member function operating on a reference data member:

struct A {
  int &ref;

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

You have to pass int to Foo<...> to achieve your goal.


For the second question, the two instantiated functions have the same parameter type, and both are templates (if one is a template, the other is a non-template function, the overload resolution will choose the later one), so the overload resolution will choose the template which is more specialized. Generally const T& is a more specialized type than T&, so the first template function is called.

0

精彩评论

暂无评论...
验证码 换一张
取 消