Pregunta

I've created a class looking something like this. The key is that it's got a main template argument plus a template base class with a default. There is also a templated copy constructor...

struct default_base{};

template <typename T, typename TBase=default_base>
class some_class : public TBase{
public:
    some_class(){}
    template <typename U, typename UBase>
    some_class(const some_class<U,UBase>& u){
        T t(U());
    }
};


int main(){
    some_class<int> a;
    return 0;
}

I'm getting this annoyingly vague compiler error, and haven't been able to spot my error...so my question is - what's really wrong? I'm using gcc 4.8.1.

g++ -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\stuff.o" "..\\src\\stuff.cpp" 
..\src\stuff.cpp: In constructor 'some_class<T, TBase>::some_class(const some_class<U,     UBase>&)':
..\src\stuff.cpp:87:10: error: default argument for template parameter for class     enclosing 'T t(U (*)())'
   T t(U());
      ^
..\src\stuff.cpp: In function 'int main()':
..\src\stuff.cpp:104:16: error: wrong number of template arguments (1, should be 2)
  some_class<int> a;
            ^
..\src\stuff.cpp:82:7: error: provided for 'template<class T, class TBase> class   some_class'
 class some_class : public TBase{
   ^
..\src\stuff.cpp:104:19: error: invalid type in declaration before ';' token
  some_class<int> a;

Edit: Spot on answers, Cheers :-) Even if I still think it should compile... this compiles...

template <typename T>
struct some_other_class{
some_other_class(){}
    template <typename U>
    some_other_class(){
        T t(U());
    }
};
¿Fue útil?

Solución

T t(U());

It is so-called "most vexing parse". It is function declaration which returns T, and takes nullary function which returns U as a parameter. Imagine:

typedef U nullary_function_return_U();
T t(nullary_function_return_U /*param_name*/)
{
    return T;
}

You can workaround it by adding parentheses:

T t( (U()) );

Or in C++11, you can use uniform initialization syntax:

T t{U{}};

most vexing indeed.The error message is really terrible and regardless of the most vexing parse, it should really compile, shouldn't it?

I have tested on GCC 4.8.1 - Error, Clang 3.4 - OK, MSVC2010 - OK. I cut down it to smallest case which triggers error on GCC:

template <typename = int>
struct Foo
{
    Foo()
    {
        int t(int()); // Error
    }
};

int main()
{
    int t(int()); // OK
    Foo<> a; // Error
}

This looks like GCC bug. I have made report to GCC Bugzilla.


Edit:

Paolo Carlini 2014-07-07 14:11:14 UTC This is already fixed mainline and 4.9.1. I'm adding the testcase and closing the bug.

Otros consejos

Do you really want to declare a function named t, taking a function returning U as argument, and returning T? When disambiguating the declaration to declare a variable t using, e.g.,

T t{U()};

it seems gcc is happy with the decaration.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top