基类模板成员函数在Derived类中被遮蔽,尽管参数列表不同

时间:2014-06-21 13:54:53

标签: c++ templates inheritance

这让我很疑惑。假设我有:

class Base
{
public:

    template<typename T>
    void foo(T& varT)
    {
        //
    }

    template<typename T, typename U>
    void foo(T& varT, U& varU)
    {
        //
    }
};

class Child : public Base
{
public:
    template<typename T, typename U, typename Z>
    void foo(T& varT, U& varU, Z& varZ)
    {
        //
    }
};

现在我试试这个:

Child c;

char cVar;
int iVar;
float fVar;

c.foo(cVar);
c.foo<int>(cVar);
c.template foo<int>(cVar);

没有一个电话有效。它们总是被错误地标记为“没有匹配的成员函数用于调用”。任何人都能指出我解决这个问题的方法吗?我在标准中读到派生对象阴影模板函数继承但标准明确表示如果它们被遮蔽,参数列表必须相同。

感谢帮助。

2 个答案:

答案 0 :(得分:7)

当您在基类中存在的派生类中具有名称时,始终会发生隐藏基本成员。基本原因是需要保护派生类使用以防止基类中的更改:假设基础中的名称未被隐藏,如果添加基类中的新重载,则可能会劫持派生成员的工作查找更确切地说,在派生类中没有任何指示基类中可能发生某些事情的基类。如果您打算使基本成员可用,则可以使用using声明:

class Child : public Base
{
public:
     using Base::foo; // declare that you want look up members from the base class

     template<typename T, typename U, typename Z>
     void foo(T& varT, U& varU, Z& varZ)
     {
         //
     }
};

在您的代码中,您有三个电话:

  1. c.foo(cVar)适用于using声明。
  2. c.foo<int>(cVar)即使使用using声明也不起作用,因为您无法将const的非int引用绑定到char左值。使用c.foo<char>(cVar)会有效。
  3. c.template foo<int>(cVar)遇到同样的问题。由于c显然不是从属名称,因此在此上下文中根本不需要使用template
  4. 如果没有using声明,您可以通过明确限定呼叫来呼叫该成员,例如:

    c.Base::foo(cVar);
    

答案 1 :(得分:0)

你需要这个: http://en.cppreference.com/w/cpp/language/using_declaration

添加到Child的定义:

using Base::foo;