【问题标题】:C++ calling a inherited method of a templated superclassC++ 调用模板化超类的继承方法
【发布时间】:2015-01-22 12:52:18
【问题描述】:

我不明白为什么下面的代码不能编译:

#include <iostream>

using namespace std;

template<typename T>
class Base {
public:
    void printTuple(T tuple) {
        std::cout << "Hello1!" << std::endl;
    }
};

template<typename T>
class Derived : public Base<T> {
public:    
    void printTuple(std::string name, T tuple) {
        std::cout << "Hello2!" << std::endl;

        printTuple(tuple);
    }
};

int main()
{
    Derived<int> d1;
    d1.printTuple("Test", 13);

    return 0;
}

我收到以下错误:

main.cpp:19:25: 错误:没有匹配函数调用 Derived::printTuple(int&)'

但是 Derived 不应该从 Base 继承具有这种签名的方法吗?

谢谢

【问题讨论】:

  • Base::printTuple(tuple);,或者在Derived的定义中的某处添加using Base::printTuple。如所写,Derived::printTuple 隐藏Base::printTuple;在您最喜欢的 C++ 教科书中阅读名称查找规则。
  • 如果签名不同也会隐藏?
  • 名称查找首先发生。仅当名称查找找到多个函数名称时,才会对这些函数执行重载解析。粗略地说,名称查找从当前作用域开始,搜索“向外”(在封闭作用域中)和“向上”(在基类中);一旦找到名称,它就会停止(即使后来证明这样命名的实体不适合给定的上下文)。

标签: c++ templates inheritance


【解决方案1】:

您应该将printTuple(tuple) 行更改为Base&lt;T&gt;::printTuple(tuple),因为基类的一个函数已隐藏。

【讨论】:

  • 没有超载,没有。它已被隐藏。
  • 对不起。你说的对。 @Barry 我用错了术语。
  • 尽管约翰的“使用”答案对于一般情况更方便(您总是调用超类方法),但我更喜欢这个,因为它仍然允许您在需要时调用子类方法。
【解决方案2】:

只需将其添加到class Derived 的public 部分的顶部即可:

using Base<T>::printTuple;

这将暴露函数的基类重载,即防止它被“隐藏”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-08
    • 1970-01-01
    • 2011-10-17
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    相关资源
    最近更新 更多