Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 739141
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 14, 20262026-05-14T08:21:57+00:00 2026-05-14T08:21:57+00:00

I observed some inconsistency between two compilers (g++ 4.5, VS2010 RC) in the way

  • 0

I observed some inconsistency between two compilers (g++ 4.5, VS2010 RC) in the way they match lambdas with partial specializations of class templates. I was trying to implement something like boost::function_types for lambdas to extract type traits. Check this for more details.

In g++ 4.5, the type of the operator() of a lambda appears to be like that of a free standing function (R (*)(…)) whereas in VS2010 RC, it appears to be like that of a member function (R (C::*)(…)). So the question is are compiler writers free to interpret any way they want? If not, which compiler is correct? See the details below.

template <typename T>
struct function_traits 
  : function_traits<decltype(&T::operator())> 
{ 
// This generic template is instantiated on both the compilers as expected.
};

template <typename R, typename C>
struct function_traits<R (C::*)() const>  { // inherits from this one on VS2010 RC
  typedef R result_type;
};

template <typename R>
struct function_traits<R (*)()> { // inherits from this one on g++ 4.5
  typedef R result_type;
};

int main(void) {
  auto lambda = []{};
  function_traits<decltype(lambda)>::result_type *r; // void *
}

This program compiles on both g++ 4.5 and VS2010 but the function_traits that are instantiated are different as noted in the code.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-14T08:21:58+00:00Added an answer on May 14, 2026 at 8:21 am

    I believe that GCC is noncompliant. N3092 §5.1.2/5 says

    The closure type for a
    lambda-expression has a public inline
    function call operator (13.5.4) whose
    param- eters and return type are
    described by the lambda-expression’s
    parameter-declaration-clause and
    trailing- return-type respectively.
    This function call operator is
    declared const (9.3.1) if and only if
    the lambda- expression’s
    parameter-declaration-clause is not
    followed by mutable.

    So while many things about the closure object’s type are implementation-defined, the function itself must be a member to be public and must be a nonstatic member to be const.

    EDIT: This program indicates that operator() is a member function on GCC 4.6, which is essentially the same as 4.5.

    #include <iostream>
    #include <typeinfo>
    using namespace std;
    
    template< class ... > struct print_types {};
    
    template<> struct print_types<> {
     friend ostream &operator<< ( ostream &lhs, print_types const &rhs ) {
      return lhs;
     }
    };
    
    template< class H, class ... T > struct print_types<H, T...> {
     friend ostream &operator<< ( ostream &lhs, print_types const &rhs ) {
      lhs << typeid(H).name() << " " << print_types<T...>();
      return lhs;
     }
    };
    
    template< class T >
    struct spectfun {
     friend ostream &operator<< ( ostream &lhs, spectfun const &rhs ) {
      lhs << "unknown";
      return lhs;
     }
    };
    
    template< class R, class ... A >
    struct spectfun< R (*)( A ... ) > {
     friend ostream &operator<< ( ostream &lhs, spectfun const &rhs ) {
      lhs << "returns " << print_types<R>()
       << " takes " << print_types<A ...>();
      return lhs;
     }
    };
    
    template< class C, class R, class ... A >
    struct spectfun< R (C::*)( A ... ) > {
     friend ostream &operator<< ( ostream &lhs, spectfun const &rhs ) {
      lhs << "member of " << print_types<C>() << ", " << spectfun<R (*)(A...)>();
      return lhs;
     }
    };
    
    template< class T >
    struct getcall {
     typedef decltype(&T::operator()) type;
    };
    
    int main() {
     int counter = 0;
    
     auto count = [=]( int ) mutable { return ++ counter; };
    
     cerr << spectfun< getcall<decltype(count)>::type >() << endl;
    }
    

    output:

    member of Z4mainEUlvE_, returns i takes i
    

    EDIT: It looks like the only problem is that pointers to certain closure call operators fail to match ptmf template patterns. The workaround is to declare the lambda expression mutable. This is meaningless if there is no capture and only (aside from fixing the problem) seems to change the const-ness of the call operator.

    template< class T >
    struct getcall {
        typedef decltype(&T::operator()) type;
        static type const value;
    };
    template< class T >
    typename getcall<T>::type const getcall<T>::value = &T::operator();
    
    int main() {
        auto id = []( int x ) mutable { return x; };
        int (*idp)( int ) = id;
        typedef decltype(id) idt;
        int (idt::*idptmf)( int ) /* const */ = getcall< decltype(id) >::value;
    
    cerr << spectfun< decltype(idp) >() << endl;
    cerr << spectfun< decltype(idptmf) >() << endl;
    cerr << spectfun< getcall<decltype(id)>::type >() << endl;
    

    output:

    returns i takes i 
    member of Z4mainEUliE0_ , returns i takes i 
    member of Z4mainEUliE0_ , returns i takes i 
    

    Without the mutable and with the const, spectfun does not print signatures for either of the last two queries.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have observed some unexpected or at least not-perfectly-matching-my-needs behaviour of textboxes bound to
I m running iperf between two machines (linux) and I can observe the mtu
What best practices should be observed when implementing HDL code? What are the commonalities
Are java primitive integers (int) atomic at all, for that matter? Some experimentation with
I analyze a VB.NET project and there are some objects (child MDI form) that
I've got this webapp that needs some memory tuning. While I'm already profiling the
This is a common question, but the explanations found so far and observed behaviour
I observe unmanaged.dll files having a unmanaged.dll.manifest file tagging along. On opening this files
Using MVC with an observer pattern, if a user action requires polling a device
Suppose you have an ActiveRecord::Observer in one of your Ruby on Rails applications -

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.