2

Please note, I can simply bypass this issue, I'm just curious about why this is actually happening.

I am trying to call a templated function on a return value from another templated function, all within a templated function. I am calling the templated functions with a templated object as a template paramter. The templated object is defined with the outer template parameter.

#include <string>

class Class
{
public:
    static Class& define( std::string name ) {
        return *new Class();
    }

    template<typename C, typename... Args>
    Class& constructor() {
        // .. Add the constructor...
        return *this;   
    }
};


template<typename T>
class iVector {
    T x; T y;
    iVector() : x( 0 ), y( 0 ) {}
    iVector( T x, T y ) : x( x ), y( y ) {}
};


typedef iVector<int> Vector;


Class& registerVector( std::string name ) {
    // This works as expected.
    Class& c = Class::define( name )
        .constructor< Vector >()
        .constructor< Vector, int, int >();
    return c;
}

// Outer templated function.
template<typename T>
Class& registerVector( std::string name ) {
    Class& c = Class::define( name )
        .constructor< iVector<T> >( )
        // This however throws a compiler error
        .constructor< iVector<T>, T, T >();
    return c;
}

int main() {
    registerVector( "Vector" );
    registerVector< iVector<int> >( "Vector" );
}

The problem seems to only occur when two of the functions are chained together, and the type being passed as a function template parameter uses the outer functions template types. Why is this happening? Is this a GCC bug? GCC Error:

TempTest.cpp: In function ‘Class& registerVector(std::string)’:
TempTest.cpp:46:27: error: expected primary-expression before ‘,’ token
TempTest.cpp:46:29: error: declaration of ‘Class T’
TempTest.cpp:41:10: error:  shadows template parm ‘class T’
TempTest.cpp:46:34: error: expected initializer before ‘>’ token
h4tch
  • 264
  • 1
  • 8

1 Answers1

6

Because those functions are being called within a template, you need to use the template keyword to disambiguate it as a call to a function template:

Class& c = Class::define( name )
        .template constructor< iVector<T> >()
        .template constructor< iVector<T>, T, T >();

For more info, see this FAQ.

Community
  • 1
  • 1
David G
  • 94,763
  • 41
  • 167
  • 253
  • Wow thanks! I've known about the keyword, but didn't really know why it needed to be used like this, now I do, thanks! – h4tch Feb 23 '14 at 04:07