Paul D
Paul D

Reputation: 333

Error when inheriting from templated class and calling templated function

I've got some template code that I'm modifying and I've run into an odd error that I can't work around. I was able to recreate the problem with the below simpler (but admittedly pointless) code snippet:

struct Widget
{
};

template <typename A>
class Foo
{
public:

    template <int numA>
    inline bool funcCall()
    {
        return numA > 0;
    }

    inline bool funcCallNoTemplate()
    {
        return false;
    }
};

template <typename B>
class Bar : public Foo<B>
{
public:

    // doesn't work
    bool concrete()
    {
        return Foo<B>::funcCall<5>();
    }

    // works fine
    bool other()
    {
        return Foo<B>::funcCallNoTemplate();
    }
};

int main()
{
    Bar<Widget> b;
    b.concrete();
    b.other();
    return 0;
}

The error I get with GCC 4.7 is the following (line 30 is the body of Bar::concrete):

example.cxx: In member function ‘bool Bar<B>::concrete()’:
example.cxx:30: error: expected primary-expression before ‘)’ token
example.cxx: In member function ‘bool Bar<B>::concrete() [with B = Widget]’:
example.cxx:43:   instantiated from here
example.cxx:30: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘int’ to binary ‘operator<’

It seems like the compiler can't even parse this correctly, am I missing something here that makes that line completely bogus?

Upvotes: 2

Views: 49

Answers (1)

Andy Prowl
Andy Prowl

Reputation: 126442

It seems like the compiler can't even parse this correctly, am I missing something here that makes that line completely bogus?

Yes. You need to use the template disambiguator:

return Foo<B>::template funcCall<5>();
//             ^^^^^^^^

This way you will tell the compiler to parse the dependent name funcCall as the name of a member function template, and the subsequent angular brackets as delimiters for the corresponding template arguments.

Without it, funcCall will be parsed as the name of a data member, while < and > will be parsed as less-than and greater-than, respectively.

Upvotes: 1

Related Questions