0

I am having a problem that I was not able to re-produce with a small self-contained example. That is, I wrote such an example (appears below), but the small example compiles, while the actual code does not.

I have a function template defined in the base:

template<class ExplicitSpace>
struct ExplicitState {
    ...
    template<class Neighbor>
    std::vector<Neighbor> successors() const {...}
    ...
};

I have the following in the deriving type:

template <typename CostType_>
struct GridMapState: ExplicitState<GridMap<CostType_>> {
    using Base = ExplicitState<GridMap<CostType_>>;
    using Base::Base; // inherit constructors
    using Base::successors; // this is supposed to do the trick

    ...
    std::vector<Neighbor> successors() const {
        // return static_cast<const Base *>(this)->template successors<Neighbor>(); 

        // the above commented version compiles
        return successors<Neighbor>(); // this does not compile
    }
    ...
};

As the comment indicates, I can explicitly call successors() of the base, but I cannot rely on using Base::successors; to make it visible.

gcc 4.8.2. gives the following:

GridMapState.h: In member function ‘std::vector<StateNeighbor<GridMapState<typename ExplicitState<GridMap<CostType_> >::CostType> > > GridMapState<CostType_>::successors() const’:
GridMapState.h:20:35: error: expected primary-expression before ‘>’ token
         return successors<Neighbor>();

Here is the small example that attempts to re-produce the problem, but it compiles just fine:

template <typename U>
struct A {
    template <typename T>
    T f() {return T(0);}
};

template <typename V>
struct B : A<int> {
    using MyT = int;
    using Base = A<int>;
    using Base::f;
    MyT f() {return f<MyT>();}
};

int main()
{
    B<int> b;
    std::cout << b.f() << std::endl;
    return 0;
}  
AlwaysLearning
  • 7,257
  • 4
  • 33
  • 68
  • 1
    You need a dependent base to repro this. – T.C. Jan 22 '16 at 11:26
  • @T.C. I think you missed the question. See the commented line of code that uses `->template` successfully. The whole point of the question is to avoid it by un-hiding the member of the base. – AlwaysLearning Jan 22 '16 at 11:55
  • 1
    And the answer is you can't. The `using` allows you to get rid of the `static_cast` but not the `template`. – T.C. Jan 22 '16 at 11:57
  • @T.C. Please correct me if the following is wrong. Since `Base` depends on `CostType_` (which is a template parameter), the compiler cannot know that Base::successors is a template on the first pass through the template class. Ah, now I understand your very first comment! – AlwaysLearning Jan 22 '16 at 12:15

0 Answers0