CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Oct 2008
    Posts
    1,456

    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.

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    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

  3. #3
    Join Date
    Oct 2008
    Posts
    1,456

    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

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: VC++2010 template bug ?

    Quote Originally Posted by superbonzo View Post
    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.

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: VC++2010 template bug ?

    Quote Originally Posted by Paul McKenzie View Post
    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" ).

    Quote Originally Posted by Paul McKenzie View Post
    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.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: VC++2010 template bug ?

    Quote Originally Posted by superbonzo View Post
    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

  7. #7
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: VC++2010 template bug ?

    Quote Originally Posted by superbonzo View Post
    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

  8. #8
    Join Date
    Nov 2003
    Posts
    1,902

    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

  9. #9
    Join Date
    Oct 2008
    Posts
    1,456

    Re: VC++2010 template bug ?

    Quote Originally Posted by D_Drmmr View Post
    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 View Post
    >> 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
  •  





Click Here to Expand Forum to Full Width

Featured