Home Dashboard Directory Help
Search

The bind cannot bind lambda expression on VC++10 by comsik76


Status: 

Closed
 as Postponed Help for as Postponed


1
0
Sign in
to vote
Type: Bug
ID: 537984
Opened: 3/1/2010 10:15:45 PM
Access Restriction: Public
1
Workaround(s)
view
1
User(s) can reproduce this bug

Description

Fisrt of all, I'm sorry about my bad English.

I'm using 2010 RC to test new expressions.
When I wanna bind a lambda expression directly,
I met a strange error.

The code is " std::bind([](int){}, 5); "

I couldn't find the reason and tried like this

auto func = [](int){};
std::bind(func, 5);

It is working correctly.
However, I think these two codes are exactly same,
and I don't wanna code like follow.

Is it an unsoluble problem since c++0x rules?
or when it will be fix?

....

And I have a irrelevant question.
template typedefs expression will be included??
I hope to code template <> using newtype = ;

at last, I'm sorry about my bad English...
Details
Sign in to post a comment.
Posted by Vidar Hasfjord on 11/22/2011 at 6:08 PM
Hi Stephan,

> Please note that lambdas supersede bind() in 99% of cases (and the remaining 1% should be handled by named functors).

The "bind" function has one advantage over lambdas; bind-expressions may evaluate to a common type, while every lambda expression evaluates to a unique type. This makes bind preferable in some conditional expressions. For example,

[code]
bool TMyClass::EvMouseWheel(uint, int zDelta, TPoint&)
{
AccumulatedDelta += zDelta; // class member
const int t = WHEEL_DELTA / 3; // threshold
auto f = [&](int a, int s) {this->PostMessage(WM_VSCROLL, a); AccumulatedDelta -= s;};
auto g = (AccumulatedDelta > 0) ? bind(f, SB_LINEUP, t) : bind(f, SB_LINEDOWN, -t);
while (abs(AccumulatedDelta) >= t) g();
}
[/code]

Using lambdas instead of "bind" in the initializer for "g", we would have to use a function wrapper to coerse the lambdas into a common type. Also, the syntax is more verbose and arguably less readable.

[code]
bool TMyClass::EvMouseWheel(uint, int zDelta, TPoint&)
{
    AccumulatedDelta += zDelta; // class member
    const int t = WHEEL_DELTA / 3; // threshold
    auto f = [&](int a, int s) {this->PostMessage(WM_VSCROLL, a); AccumulatedDelta -= s;};
    typedef function<void()> G;
    G g = (AccumulatedDelta > 0) ? G([&]() {f(SB_LINEUP, t);}) : G([&]() {f(SB_LINEDOWN, -t);});
    while (abs(AccumulatedDelta) >= t) g();
}
[/code]

Using a named functor would add much obfuscating verbosity.

[code]
bool TMyClass::EvMouseWheel(uint, int zDelta, TPoint&)
{
    AccumulatedDelta += zDelta; // class member
    const int t = WHEEL_DELTA / 3; // threshold
    struct F
    {
     TWindow& w;
     int& d;
     int a;
     int s;
     F(TWindow& w_, int& d_, int a_, int s_) : w(w_), d(d_), a(a_), s(s_) {}
     void operator()() {w.PostMessage(WM_VSCROLL, a); d -= s;};
    };
    F f = (AccumulatedDelta > 0) ?
     F(*this, AccumulatedDelta, SB_LINEUP, t) :
     F(*this, AccumulatedDelta, SB_LINEDOWN, -t);
    while (abs(AccumulatedDelta) >= t) f();
}
[code]

Regards,
Vidar Hasfjord
Posted by Microsoft on 3/3/2010 at 6:32 PM
Hi,

Thanks for reporting this bug. It's too late for us to fix this in VC10, but we're keeping this bug active so that it can be fixed in VC11.

Please note that lambdas supersede bind() in 99% of cases (and the remaining 1% should be handled by named functors).

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 Microsoft on 3/2/2010 at 1:00 AM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you
Sign in to post a workaround.
Posted by Vidar Hasfjord on 11/22/2011 at 6:24 PM
The workaround in the original post does not work for me. Both code snippets produce errors in "bind".

My workaround is to use a std::function wrapper:

[code]
    typedef function<void(int)> F;

    bind(F([](int) {}), 5);

    F func = [](int){};
    bind(func, 5);
[/code]

Regards,
Vidar Hasfjord