c++boostboost-tuples

C++ Cannot call base class method from within derived class


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


Solution

  • 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: