尽管需要,但从未调用基类的重载函数

时间:2012-05-06 03:04:19

标签: c++ templates inheritance overloading

我正在尝试编写一个同时包含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()。

我错过了什么吗?

3 个答案:

答案 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&&作为参数。