0

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

我错过了什么吗?

4

3 回答 3

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
于 2012-05-06T03:23:38.437 回答
1

如果您真的看到了您所说的使用您发布的代码的结果,那么这绝对是一个编译器错误。当 T 为“int”时,您不应使用常量调用 f(T&)。即使发生了某种隐藏,我认为 using 可以解决这个问题,程序应该完全无法编译而不是调用错误的函数。

于 2012-05-06T04:10:34.653 回答
1

您正在使用 Visual Studio 2010,它提供此功能作为临时绑定到非常量引用的扩展。这就是为什么它T&在两种情况下都调用版本。这个编译器扩展,如果有的话,应该被称为编译器错误,因为它取代了标准定义的行为。

但是,在标准 C++ 中,从整数文字创建的临时对象8不能绑定到非常量引用,因此调用必须解析为T&&作为参数的函数。

于 2012-05-06T04:20:37.237 回答