2013-11-24 678 views
5

这是我的第一个问题,我希望我做的一切都是正确的。C++无法从派生类中调用基类方法

我尝试从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; 
} 

我不知道为什么我可以从主功能

a.get<0>() = 5; 

但不能从A& getVal0()方法中访问get<0>()方法:

error: 'get' was not declared in this scope 

第二个回归线是我的尝试sc OPE方法调用基类:

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

这产生不同的错误

error: expected primary-expression before ')' token 

调用外部函数'的boost ::元组::获得< 0>(*此)的作品。这个解决方法对我来说没问题。但我仍然想知道为什么我现在不能使用元组方法。

在升压文件是Visual C++

提示的通知! MS Visual C++编译器不支持成员获取函数。此外,编译器在找到非成员get函数时没有明确的命名空间限定符。因此,在编写应使用MSVC++ 6.0进行编译的代码时,所有获取调用应该被限定为:tuples :: get(a_tuple)。

但是我使用GCC 4.5.2 & 4.8.1

在此先感谢

+5

+1我必须这样说:除了标的物之外,您的问题应作为本网站上发布的任何新用户的示例。 (1)你认为你有的问题,(2)展示这个问题的示例代码,(3)试图解决问题,(4)每个人的每个结果尝试,(5)你使用的工具,包括版本信息,以及(6)研究你认为根本问题可能是什么。对于一般的职位来说,这很棒;对于一个*第一*邮政来说,它非常出色,很少见到这种交付。 – WhozCraig

+0

WhozCraig这是非常好的,你可以给一个初学者这么多好话和积极的建议 – 4pie0

+0

@piotruś当这样的问题发布时不难。我很死 - 认真对待这个模范。我只希望OP知道如何标记解决方案,因为我非常确定Dietmar有这个解决方案。 = P – WhozCraig

回答

3

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

this->template get<0>() 

this部分是需要使它成为一个依赖查找(你也可以使用适当的类的资格,但这有点痛苦和不必要的除非你隐藏了一个基类的名字)。 template部分有必要告诉编译器,从属名称(get)碰巧是一个模板。

为什么需要this(或其他一些资质)和template的主要原因是对模板的两相编译模型:

  • 不立即依赖于一个模板参数某种形式的任何名称只在阶段I期间查看,即在模板被定义的上下文中。由于模板参数未知,因此基类的确切布局未知(可能是专用的),因此基类中的任何名称都将被忽略。使用任何使名称取决于模板参数的限定,例如使用this->将查找移动到阶段II,即,当模板被实例化时。
  • 一旦一个名字是相关的,如果一个表达式涉及一个<字符,而模板在阶段I中被解析,也就是说,当模板参数尚不知道时,就会产生歧义:<既可以是成员函数调用的显式模板参数,或者它可以是小于运算符。由于模板参数的明确提及很少见(至少,当这些规则制定时很少见),因此默认情况下它被认为是小于运算符。要声明该名称实际上是一个具有明确指定的模板参数的成员函数模板,它需要在关键字template之前(非常类似于需要typename的类型)。
+0

最大的问题是为什么会发生这种情况。感谢'this-> template'提示我找到了[link](http://stackoverflow.com/questions/5533354/what-does-a-call-to-this-template-snamename-do)。 Stroustrups中$ C.13.6 C++编程语言解释了这个问题。但我仍然不确定为什么这是派生类中需要的。 –

+0

@EvilAzrael:我在答案中加了一些解释。 –

+0

感谢您的解释。 :-) –

相关问题