这是我的第一个问题,我希望我做的一切都是正确的。
我尝试从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&lt; 0&gt;(* this)有效。这个解决方法对我来说没问题。但我仍然想知道为什么我不能在这一点上使用元组方法。
在boost文档中是Visual C ++的通知
请注意! MS Visual C ++编译器不支持成员获取函数。此外,编译器在没有显式名称空间限定符的情况下找到非成员get函数时遇到问题。因此,在编写应该使用MSVC ++ 6.0编译的代码时,所有get调用都应该被限定为:tuples :: get(a_tuple)。
但我正在使用GCC 4.5.2&amp; 4.8.1
提前致谢
答案 0 :(得分:5)
假设基类中有一个get<I>()
成员函数模板,您可能想要使用
this->template get<0>()
需要this
部分才能使其成为依赖查找(您也可以使用适当的类限定,但除非您隐藏基类名称,否则这有点痛苦和不必要)。 template
部分是告诉编译器依赖名称(get
)碰巧是模板所必需的。
需要this
(或其他一些限定条件)和template
的主要原因是模板的两阶段编译模型:
this->
,将查找移动到阶段II,即,当模板被实例化时。<
字符,而模板在阶段I中被解析,即当模板参数尚未知道时,则会产生歧义:{{1}可以是成员函数调用的显式模板参数的开头,也可以是小于运算符。由于明确提到模板参数很少(嗯,至少在制定这些规则时很少见),默认情况下假定它是小于运算符。要声明该名称实际上是具有明确指定的模板参数的成员函数模板,则需要在其前面加上关键字<
(非常类似于需要template
的类型)。