Daniel B. Chapman
Daniel B. Chapman

Reputation: 4687

Trouble casting lambda to std::function

I'm having trouble with MiniGW when attempting to create an API. This works fine in MSVC11 (Visual Studio 2012 C++ compiler). My compiler (I believe) is set up properly QMAKE_CXXFLAGS += -std=c++0x, after all I do have a lambda error message.

For some more explanation:

typedef std::function<bool(Item)> WHERE;//I was attempting to provide an explicit cast, 'auto' works fine in MSVS

Group where(WHERE func);//A simple "foreach boolean" search

Using the above->

Groups::WHERE where = [](Item & x)-> bool{return x.has("NEW");};

results in:

tst_groupstest.cpp:257: error: conversion from 'GroupsTest::groups()::__lambda1' to non-scalar type 'Groups::WHERE {aka std::function}' requested Groups::WHERE where = [](Item & x)-> bool{return x.has("NEW");};

I'm hoping this is something obvious, I just can't find it. I'm planning to support Linux and Mac down the road with this project so I'd love to figure this one out sooner than later.

Here's my current workaround and I'd prefer to stay away from this if at all possible (after all, the reason I designed it the API with lambdas in mind was to have concise code blocks that are obvious).

This section compiles (it isn't using lambdas)

struct lambdaCueListstdFunc{
    bool operator()(Groups::Item x)
    {
        return x.has("NEW");
    }
};

/**
 * Selects all cues for a particular list
 * @brief getCueList
 * @param list
 * @return a vector of all the cues for this list sorted by number.
 */
std::vector<Groups::Item> CueService::getCueList(std::string list)
{
    std::function<bool(Groups::Item)> where = lambdaCueListstdFunc();
//    auto where = [&list] (Groups::Item & x) ->
//    {
//        return x.get(la::cues::List) == list;
//    };
    std::vector<Groups::Item> result = cues()->where(where).sort(la::cues::NUMBER);
    return result; 

}

Upvotes: 0

Views: 2138

Answers (2)

peter karasev
peter karasev

Reputation: 2614

This came up for me for a different reason: the by-value type passed through the lambda args had a member of type std::unique_ptr and hence was not copyable.

Fix 1: change the member to be std::shared_ptr

Fix 2: pass by (const) reference

Upvotes: 0

Praetorian
Praetorian

Reputation: 109289

The function signature you provided to std::function is different from that of the lambda you're trying to assign to it.

typedef std::function<bool(Item)> WHERE; // <-- Takes argument by value

Groups::WHERE where = [](Item & x)-> bool{return x.has("NEW");};
//                           ^^^
// The lambda takes argument by reference

Change either one to match the other, depending on whether you want to pass by value or reference.

Upvotes: 5

Related Questions