this is my first question, I hope I do everything correct.
I try to derive a class from a boost tuple. Boost's tuples provide a get() template method to access the individual fields. Interestingly I cannot use the method from within the derived class.
The following code shows the problem:
#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;
}
I wonder why I can access the get<0>()
method from the main function
a.get<0>() = 5;
but not from within the A& getVal0()
method:
error: 'get' was not declared in this scope
The second return line was my try to scope the method call to the base class:
return boost::tuple<A>::get<0>();
And this generates a different error
error: expected primary-expression before ')' token
Calling the external function `boost::tuples::get<0>(*this) works. And this workaround is okay to me. But I am still wondering why I cannot use the tuple method at this point.
In the boost documentation is a notice for 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.
But I am using GCC 4.5.2 & 4.8.1
Thanks in advance
Assuming there is a get<I>()
member function template in the base class, you probably want to use
this->template get<0>()
The this
part is needed to make it a dependent look-up (you can use proper class qualification, too, but that's a bit of a pain and unnecessary unless you are hiding a base class name). The template
part is necessary to tell the compiler that the dependent name (get
) happens to be a template.
The primary reason why this
(or some other qualification) and template
are needed is the two phase compilation model for templates:
this->
, moves the look-up into phase II, i.e., when the template is instantiated.<
character while the template is parsed in phase I, i.e., when the template arguments are not, yet, known: The <
can either be the start of an explicit template argument for a member function call or it can be the less-than operator. Since explicit mention of template arguments is rare (well, at least, it was rare when these rules were made), it is assumed to be the less-than operator by default. To state that the name is actually a member function template with an explicitly specified template argument, it needs to be preceded by the keyword template
(pretty similar to types needing a typename
).