Thread: Automatically wrap lamda function with std::function

  1. #1
    Registered User
    Join Date
    Dec 2013
    Posts
    241

    Automatically wrap lamda function with std::function

    Hi all,
    My Problem goes like this:
    If I want to save function in a std::map, I have the map value be either pointer to function or either std::function.

    If I want to allow lamda functions to be saved in the map , and the lamda uses captures , in order for it work , the value must be std::function , and I must wrap the lamda with std::function.

    for example , look at this snippet:

    Code:
    class SomeClass{
    
    private:
    static std::map<void* , std::function<void()>> functionMap;
    
    public :
    void setNewKeyValue (void* key ,std::function<void()>& function){
    functionMap[key] = function;
    }
    
    void setNewKeyValue (void* key ,void(*function)()){
    functionMap[key] = function;
    }
    
    };
    
    int main (void){
    SomeClass someObject;
    int x;
    double y =8.8 ; //dumm example, just to clarify the question
    SomeObject.setNewKeyValue((void*)&x,std::function([&y]{y=-1;}));
    return 0;
    }
    my question is , is there some way of setNewKeyValue to wrap the lamda expression from the inside so the outside developer won't be needing to wrap every lamda that uses capture with std::function?
    or even something else , is there any "clean" solution to allow lamda functions with uses captures to be stored in a std::map?
    Last edited by Dave11; 02-02-2015 at 09:41 AM.

  2. #2
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    I don't think you need to do that wrapping.
    Unless I have totally misunderstood your question..the following code builds fine:
    Code:
    #include<map>
    #include<functional>
    int main()
    {
        int x = 6;
        std::map<int, std::function<void()>> map;
        map[2] = [&x](){};
    }

  3. #3
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    your code is slightly different, if you try this:
    Code:
    #include<map>
    #include<functional>
    
    std::map<int, std::function<void()>> map;
    
    void setFunction(int i, std::function<void()>& f){
        map[i] = f;
    }
    
    int main()
    {
        int x = 6;
        setFunction(2, [&x](){});
    }
    it doesn't compile.
    interestingly , if we pass the lamda by value , AKA void setFunction(int i, std::function<void()> f) it does.
    I wonder what kind of effect on the time and memory passing lamda function by value makes.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Code:
    static std::map<void* , std::function<void()>> functionMap;
    O_o

    Code:
    SomeObject.setNewKeyValue((void*)&x,std::function([&y]{y=-1;}));
    o_O

    You shouldn't use that particular combination of code.

    If your use was in a different function, I could show you how to make the code explode.

    As is, you are just asking for trouble.

    When `someObject' dies, the references are lost. You can't reliable determine the value of `&x', but the function called would use a reference to update an dead object if you could.

    *shrug*

    The `setNewKeyValue' shouldn't take the `std::function<???>' object as a mutable reference. You can take the `std::function<???>' object as a constant reference. Preferably given the C++11 code, you could use perfect forwarding and `std::map<???>::emplace' allowing you to implement just one version of `setNewKeyValue' which will try to do the right thing.

    [Edit]
    By the by, the cast is unnecessary and ugly. You should remove the cast.
    [/Edit]

    Soma
    Last edited by phantomotap; 02-02-2015 at 10:02 AM.
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Dave11 View Post
    it doesn't compile.
    interestingly , if we pass the lamda by value , AKA void setFunction(int i, std::function<void()> f) it does.
    The problem is not that you can't convert lambda -> std::function. The problem is that you're trying to pass a temporary to a non-const reference. The above code is non-standard, but supported at least on msvc as an extension.
    You should take the function object by const reference and then make a copy of it.

    For example:
    Code:
    #include <map>
    #include <functional>
    
    std::map<int, std::function<void()>> map;
    
    void setFunction(int i, const std::function<void()>& f)
    {
    	map[i] = f;
    }
    
    int main()
    {
    	int x = 6;
    	setFunction(2, [&x]() {});
    }
    This compiles fine.
    Btw, yeah, don't store references to local variables.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    Of course , this is just some example code to illustrate the problem. I see what was I missing, thanks.

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Of course , this is just some example code to illustrate the problem. I see what was I missing, thanks.
    O_o

    Did you understand why the code was missing what was missing?

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  8. #8
    Registered User
    Join Date
    Dec 2013
    Posts
    241
    yes , I tried to pass a Temporary- lamda-function as argument on a function with reference std::function as parameter.
    only const references can be bind to temporaries, no regular references , and that was the problem (lamda function are not different here).

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Dave11 View Post
    ...only const references can be bind to temporaries...
    And r-value references.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function name to wrap the standard strncpy function.
    By stahta01 in forum C Programming
    Replies: 5
    Last Post: 11-07-2014, 12:12 PM
  2. Replies: 3
    Last Post: 01-15-2014, 04:15 AM
  3. Help with Simple Word Wrap Function
    By kabuki in forum C Programming
    Replies: 9
    Last Post: 10-22-2013, 07:57 PM
  4. Help with Word Wrap function
    By kabuki in forum C Programming
    Replies: 2
    Last Post: 10-15-2013, 09:51 AM
  5. Replies: 9
    Last Post: 01-02-2007, 04:22 PM