我正在尝试编写一个同时包含int和int&的容器。 在一个班级中完成:
template <class T>
class unified_class
{
public:
virtual void f(T &i){}
virtual void f(T &&i) {}
};
主叫:
unified_class<int> u;
u.f(8); // going to the second method
int a = 9;
u.f(a); // going to the first method
但是当我试图将它分成两个类之间时,会发生一些奇怪的事情:
template <class T>
class base_class
{
public:
virtual void f(T &&i) { /* it never reaches here*/}
};
template <class T>
class derived_class : public base_class<T>
{
public:
using base_class<T>::f;
virtual void f(T &i){}
};
从之前调用相同的函数调用,导致在两种情况下调用派生类的f()。
我错过了什么吗?
答案 0 :(得分:1)
我没有看到g ++ 4.6.3的问题。这是我使用的代码:
#include <iostream>
using std::cerr;
template <class T>
class base_class
{
public:
virtual void f(T &&i) { cerr << "base_class\n"; }
};
template <class T>
class derived_class : public base_class<T>
{
public:
using base_class<T>::f;
virtual void f(T &i) { cerr << "derived_class\n"; }
};
int main(int argc,char **argv)
{
derived_class<int> u;
u.f(8); // going to the second method
int a = 9;
u.f(a); // going to the first method
}
我得到了这个结果:
base_class
derived_class
答案 1 :(得分:1)
如果你真的看到结果,你说你已经发布了你发布的代码,那么这绝对是一个编译器错误。当T为“int”时,你不应该用常量调用f(T&amp;)。即使存在某种隐藏,我认为使用它会解决这个问题,程序应该完全无法编译而不是调用错误的函数。
答案 2 :(得分:1)
您使用的是Visual Studio 2010,它提供此功能作为临时绑定到非const 引用的扩展。这就是它在两种情况下都调用T&
版本的原因。这个编译器扩展,如果有的话,应该被称为编译器错误,因为它替换标准定义的行为。 / p>
但是,在标准C ++中,从整数文字8
创建的临时对象不能绑定到非const 引用,因此调用必须解析为函数将T&&
作为参数。