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).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With