-
July 15th, 2011, 03:49 AM
#1
VC++2010 template bug ?
I have an issue with VC++2010, and before opening a Microsoft Connect report I'd like to share the problem to see if I'm missing something or not;
consider the following code ( whose sole purpose is to reproduce the problem ):
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, typename C<T>::type = C<T>::type() ) { /* whatever */ }
int main(){ A a; f(a); }
so far so good, everything is ok as expected. But try defining f after declaration:
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, 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); }
and VC complains with the "error C2064: term does not evaluate to a function taking 0 arguments" referred to the declaration line ...
ah, note that Comeau does not complain instead, as expected.
-
July 16th, 2011, 04:36 PM
#2
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
-
July 17th, 2011, 02:37 AM
#3
Re: VC++2010 template bug ?
I see, but the problem is that I need the default constructed value parametrized by T ... 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
-
July 17th, 2011, 12:03 PM
#4
Re: VC++2010 template bug ?
Originally Posted by superbonzo
I see, but the problem is that I need the default constructed value parametrized by T ... 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
Last edited by Paul McKenzie; July 17th, 2011 at 12:06 PM.
-
July 18th, 2011, 02:16 AM
#5
Re: VC++2010 template bug ?
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 , with the same error ( my VC++2010 version is "10.0.40219.1 SP1Rel" ).
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.
-
July 18th, 2011, 03:24 AM
#6
Re: VC++2010 template bug ?
Originally Posted by superbonzo
I tried your code and ... it doesn't work for me , 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
-
July 19th, 2011, 11:14 AM
#7
Re: VC++2010 template bug ?
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.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
July 19th, 2011, 11:49 AM
#8
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
-
July 19th, 2011, 12:13 PM
#9
Re: VC++2010 template bug ?
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 ...
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 ...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|