Home Dashboard Directory Help
Search

std::reference_wrapper does not work with lambda functions by i-photon


Status: 

Closed
 as Fixed Help for as Fixed


2
0
Sign in
to vote
Type: Bug
ID: 696151
Opened: 10/21/2011 4:01:02 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
0
Workaround(s)
view
1
User(s) can reproduce this bug

Description

Below is a simplified version of what I encountered:

auto f = []()->int{return 1;};

int i = std::ref(f)();

This works as expected with g++ 4.6; the reference wrapper calls the function and i == 1 afterward.

With MSC and the default libraries I get:

"error C2440: 'initializing' : cannot convert from 'void' to 'int'"

If "f" were a functor of my design, I'd get:

"...\Microsoft Visual Studio 10.0\VC\include\xxcallobj(7): error C2562: 'std::tr1::_Callable_obj<_Ty,_Indirect>::_ApplyX' : 'void' function returning a value"
Details
Sign in to post a comment.
Posted by Microsoft on 10/25/2011 at 7:44 PM
Oh, I just noticed that you also mentioned user-defined functors. Those are automatically recognized by VC11 (using the same machinery as for lambdas). For VC10 SP1, give your user-defined functor a result_type typedef, which will make it work with reference_wrapper:

C:\Temp>type kitty.cpp
#include <stdio.h>
#include <functional>
using namespace std;

class Functor {
public:
    explicit Functor(int n) : m_n(n) { }

    int operator()() {
        return ++m_n;
    }

    typedef int result_type;

private:
    int m_n;
};

int main() {
    int x = 0;

    Functor fa(x);
    Functor fb = fa;
    reference_wrapper<Functor> fr = ref(fa);

    x = 1729;

    for (int i = 0; i < 4; ++i) {
        int a = fa();
        int b = fb();
        int r = fr();

        printf("fa() %d ; fb() %d ; fr() %d ; x %d\n", a, b, r, x);
    }
}

[VC10 SP1]
C:\Temp>cl /EHsc /nologo /W4 kitty.cpp
kitty.cpp

C:\Temp>kitty
fa() 1 ; fb() 1 ; fr() 2 ; x 1729
fa() 3 ; fb() 2 ; fr() 4 ; x 1729
fa() 5 ; fb() 3 ; fr() 6 ; x 1729
fa() 7 ; fb() 4 ; fr() 8 ; x 1729

This is due to the change from TR1, which had to work with the C++98/03 Core Language, to C++11, which can take advantage of new Core Language features like decltype.

STL
Posted by Microsoft on 10/25/2011 at 7:32 PM
Hi,

Thanks for reporting this bug. We've already fixed it, and you should be able to observe the fix in the VC11 Developer Preview. Here's an example:

C:\Temp>type kitty.cpp
#include <stdio.h>
#include <functional>
using namespace std;

int main() {
    int x = 0;

    auto la = [x]() mutable { return ++x; };
    auto lb = la;
    auto lr = ref(la);

    x = 1729;

    for (int i = 0; i < 4; ++i) {
        int a = la();
        int b = lb();
        int r = lr();

        printf("la() %d ; lb() %d ; lr() %d ; x %d\n", a, b, r, x);
    }
}

[VC10 SP1]
C:\Temp>cl /EHsc /nologo /W4 kitty.cpp
kitty.cpp
kitty.cpp(17) : error C2440: 'initializing' : cannot convert from 'void' to 'int'
        Expressions of type void cannot be converted to other types

[VC11]
C:\Temp>cl /EHsc /nologo /W4 kitty.cpp
kitty.cpp

C:\Temp>kitty
la() 1 ; lb() 1 ; lr() 2 ; x 1729
la() 3 ; lb() 2 ; lr() 4 ; x 1729
la() 5 ; lb() 3 ; lr() 6 ; x 1729
la() 7 ; lb() 4 ; lr() 8 ; x 1729

If you have any further questions, feel free to E-mail me at stl@microsoft.com .

Stephan T. Lavavej
Visual C++ Libraries Developer
Posted by MS-Moderator10 [Feedback Moderator] on 10/23/2011 at 11:41 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by MS-Moderator10 on 10/23/2011 at 6:44 PM
Thank you for your feedback, We are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly (http://support.microsoft.com/)
Sign in to post a workaround.