C++ 无法从派生类中调用基类方法

标签 c++ boost boost-tuples

这是我的第一个问题,我希望我做的一切都是正确的。

我尝试从 boost 元组派生一个类。 Boost 的元组提供了一个 get() 模板方法来访问各个字段。有趣的是,我不能使用派生类中的方法。

以下代码显示了问题:

#include <iostream>
#include <boost/tuple/tuple.hpp>
using namespace std;

template<typename A>
class Derived : public boost::tuple<A>
{
public:
    Derived() : boost::tuple<A>() {}

    A& getVal0()
    {
        return get<0>();
        // does not compile:
        //error: 'get' was not declared in this scope

        return boost::tuple<A>::get<0>();
        // does not compile
        //error: expected primary-expression before ')' token

        return boost::tuples::get<0>(*this);
        //works
    }
};  

int main() {
    Derived<int> a;

    a.get<0>() = 5;

    cout << a.get<0>() << endl; 
    cout << a.getVal0() << endl; 
    return 0;
}

我想知道为什么我可以访问 get<0>()来自主函数的方法

a.get<0>() = 5;

但不是来自 A& getVal0()方法:

error: 'get' was not declared in this scope

第二个返回行是我尝试将方法调用范围限定到基类:

return boost::tuple<A>::get<0>();

这会产生不同的错误

error: expected primary-expression before ')' token

调用外部函数 `boost::tuples::get<0>(*this) 有效。这个解决方法对我来说没问题。但是我仍然想知道为什么此时不能使用元组方法。

在 boost 文档中有一条针对 Visual C++ 的通知

Note! The member get functions are not supported with MS Visual C++ compiler. Further, the compiler has trouble with finding the non-member get functions without an explicit namespace qualifier. Hence, all get calls should be qualified as: tuples::get(a_tuple) when writing code that should compile with MSVC++ 6.0.

但我使用的是 GCC 4.5.2 & 4.8.1

提前致谢

最佳答案

假设有一个 get<I>()基类中的成员函数模板,你可能想用

this->template get<0>()

this部分需要使其成为依赖查找(您也可以使用适当的类限定,但这有点痛苦且不必要,除非您隐藏基类名称)。 template部分是必要的,以告诉编译器依赖名称 ( get) 恰好是一个模板。

this 的主要原因(或其他一些资格)和 template需要的是模板的两阶段编译模型:

  • 任何不立即以某种形式依赖于模板参数的名称仅在阶段 I 中查找,即在定义模板的上下文中查找。由于模板参数是未知的,因此基类的确切布局是未知的(它可能是专门的),基类中的任何名称都将被忽略。使用任何导致名称依赖于模板参数的限定,例如,使用 this-> ,将查找移动到第二阶段,即实例化模板时。
  • 一旦名字是从属的,如果表达式涉及 < 就会产生歧义。在阶段 I 中解析模板时的字符,即当模板参数未知时: <可以是成员函数调用的显式模板参数的开始,也可以是小于运算符。由于很少明确提及模板参数(好吧,至少在制定这些规则时很少见),默认情况下假定它是小于运算符。要声明该名称实际上是具有显式指定模板参数的成员函数模板,需要在其前面加上关键字 template。 (与需要 typename 的类型非常相似)。

关于C++ 无法从派生类中调用基类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20180694/

相关文章:

c++ - sql参数的最佳STL容器

c++ - boost & asio 作为 Cmake 大项目的一部分

c++ - 如何将 boost::tuple 分配给 boost::shared_ptr

c++ - Boost::message_queue::receive/send 不适用于最新版本

c++ - boost::spirit 示例无法编译

c++ - 使用 boost::mpl::vector 创建可变参数模板?

c++ - 异步纹理加载工具

c++ - <iosfwd> header 是什么?

c++ - 在 C++ 中将 vector 解包为函数参数的任何解决方案?