Re: VC++2010 template bug ?
The following compiles successfully with VC 2010:
Code:
struct A {}; // a type
struct B {}; // a trait value
template < class T >
struct C
{
typedef B type;
};
template < class T >
void f( T, typename C<T>::type = B() );
template < class T >
void f( T, typename C<T>::type /* = C<T>::type() */ ) { /* whatever */ }
int main(){ A a; f(a); }
VC 2010 thinks that "type()" is an error. Replacing it with the actual object name being default constructed is the only way I've seen to work around this issue.
Regards,
Paul McKenzie
Re: VC++2010 template bug ?
I see, but the problem is that I need the default constructed value parametrized by T ... :cry: for now, I'll stick with putting the function body definition along with its declaration ...
the funny thing is that an apparently unrelated syntactical part of the function ( the function body ) triggers the error; well then, I'll issue a Microsoft Connect report and see what happens :)
Re: VC++2010 template bug ?
Quote:
Originally Posted by
superbonzo
I see, but the problem is that I need the default constructed value parametrized by T ... :cry: for now, I'll stick with putting the function body definition along with its declaration ...
It has something to do with the name type. If you changed it to another name, it will compile:
Code:
struct A {}; // a type
struct B {}; // a trait value
template < class T >
struct C
{
typedef B type_;
};
template < class T >
void f( T, typename C<T>::type_ = C<T>::type_());
template < class T >
void f( T, typename C<T>::type_ /* = C<T>::type_() */ ) { /* whatever */ }
int main(){ A a; f(a); }
Just placing the underscore did the trick for me. Maybe there is something in that word type that makes it a keyword (is it a new keyword introduced in C+0x?).
Personally, I make it a habit to not use names that could be keywords or could easily conflict with a definition in a header file somewhere. The word type is an example -- who knows if you included some header, that type is a #define or a macro lurking somewhere.
Regards,
Paul McKenzie
Re: VC++2010 template bug ?
Quote:
Originally Posted by
Paul McKenzie
Just placing the underscore did the trick for me
I tried your code and ... it doesn't work for me :confused:, with the same error ( my VC++2010 version is "10.0.40219.1 SP1Rel" ).
Quote:
Originally Posted by
Paul McKenzie
Maybe there is something in that word type that makes it a keyword (is it a new keyword introduced in C+0x?).
[...] who knows if you included some header, that type is a #define or a macro lurking somewhere.
this cannot be the case, because the standard definition of the so called TransformationTrait concept requires a member named "type"; moreover, it's customary to name "type" a metafunction "return value": boost type traits, boost MPL and all boost libraries follow this convention as well.
BTW, the original code manifesting this issue uses both "type" returning metafunctions and traits with specific type names.
Re: VC++2010 template bug ?
Quote:
Originally Posted by
superbonzo
I tried your code and ... it doesn't work for me :confused:, with the same error ( my VC++2010 version is "10.0.40219.1 SP1Rel" ).
I'm not at my machine now, but I was able to compile the updated version with no problems. Still doesn't make sense to me, and I believe it is a bug in the compiler. As you've stated, "type" is used a lot in boost.
Regards,
Paul McKenzie
Re: VC++2010 template bug ?
Quote:
Originally Posted by
superbonzo
and VC complains with the "error C2064: term does not evaluate to a function taking 0 arguments" referred to the declaration line ...
Moving the definition below main also prevents the error, though that's probably not a very practical workaround.
Re: VC++2010 template bug ?
>> for now, I'll stick with putting the function body definition along with its declaration
That seems to be the most practical work-around.
Code:
struct A {}; // a type
struct B {}; // a trait value
template < class T > struct C { typedef B type; }; // a trait class
// template < class T >
// void f( T a, typename C<T>::type b = typename C<T>::type() );
template < class T >
void f( T a, typename C<T>::type b = typename C<T>::type() ) { /* whatever */ }
int main(){ A a; f(a); }
That works with GCC and MSVC.
GCC wanted the extra typename, but that didn't help MSVC - neither did the variable names.
gg
Re: VC++2010 template bug ?
Quote:
Originally Posted by
D_Drmmr
Moving the definition below main also prevents the error, though that's probably not a very practical workaround.
yes, it seems also working whenever an instantion occurs before the compiler find the function definition, but again not that useful ...
Quote:
Originally Posted by
Codeplug
>> for now, I'll stick with putting the function body definition along with its declaration
That seems to be the most practical work-around.
agreed, I can also forward arguments to an "implementation" function defined elsewhere if needed ...
BTW, I'm quite disappointed by the current VC template support, I have to say. For example, I thought they would have fixed SFINAE support in this release, whilst we're still forced to use workarounds like boost::lazy_enable_if in some cases ... :mad: