std::for_each on a map containing unique_ptr

Discussion in 'C++' started by Brice Gagnage, Apr 4, 2012.

  1. Hi folks,

    Given this piece of code:

    std::map< int, std::unique_ptr< int > > map;

    std::for_each( std::begin( map ), std::end( map ),
    [&] ( const std::pair< int, std::unique_ptr< int > >& pair )
    {
    cout << pair.first;
    } );

    My compiler pops an error: for_each is trying to create a pair, thus taking
    map elements' unique_ptr's as parameters. At this point, I don't understand
    why for_each has to create a pair, since I'm asking explicitly for a const ref
    in my lambda. Is there any way to make this map work with this algorithm ?
    Any help appreciated.

    Thanks in advance,

    --
    Brice Gagnage
    Brice Gagnage, Apr 4, 2012
    #1
    1. Advertising

  2. On 2012-04-04, Brice Gagnage <> wrote:
    > My compiler pops an error: for_each is trying to create a pair, thus taking
    > map elements' unique_ptr's as parameters. At this point, I don't understand
    > why for_each has to create a pair, since I'm asking explicitly for a const ref
    > in my lambda. Is there any way to make this map work with this algorithm ?


    I found the solution, the type of the parameter is incorrect. The lambda
    should expect here a const std::pair< const int, std::unique_ptr< int >
    >&


    It seems that in the for_each implementation, the map's key is casted to const
    to avoid the possibility of changing it inside the lambda. Since the
    parameter I used was different, the compiler simply tried to create
    similar pair with the key as const.

    Anyway, I think the best practice here would have been to use the map
    iterator reference_type instead of writing it myself.

    Hope this helps,

    --
    Brice Gagnage
    Brice Gagnage, Apr 4, 2012
    #2
    1. Advertising

  3. Le 04/04/2012 14:26, Brice Gagnage a écrit :
    > Hi folks,
    >
    > Given this piece of code:
    >
    > std::map< int, std::unique_ptr< int> > map;
    >
    > std::for_each( std::begin( map ), std::end( map ),
    > [&] ( const std::pair< int, std::unique_ptr< int> >& pair )
    > {
    > cout<< pair.first;
    > } );
    >
    > My compiler pops an error: for_each is trying to create a pair, thus taking
    > map elements' unique_ptr's as parameters. At this point, I don't understand
    > why for_each has to create a pair, since I'm asking explicitly for a const ref
    > in my lambda. Is there any way to make this map work with this algorithm ?
    > Any help appreciated.
    >
    > Thanks in advance,
    >


    Hello Miaou

    std::map::value_type is defined as
    typedef pair<const Key, Type> value_type

    so you are trying to cast a pair< Key, Type> to a const pair<const Key,
    Type>&

    So by changine the signature of the paire as std::pair< const int,...
    it should fix the issue


    Hamster

    :)
    --
    Vianney Lançon
    Vianney Lançon, Apr 4, 2012
    #3
  4. Brice Gagnage <> wrote:
    > Anyway, I think the best practice here would have been to use the map
    > iterator reference_type instead of writing it myself.


    Or you could just do a: for(auto& elem: map) std::cout << elem.first;

    (But yes, I understand that this solution only works as a substitute
    for a for_each() that traverses the entire data container, not one that
    traverses only a subrange, or for a completely different algorithm.)
    Juha Nieminen, Apr 4, 2012
    #4
  5. Brice Gagnage

    red floyd Guest

    On 4/4/2012 9:28 AM, Juha Nieminen wrote:
    > Brice Gagnage<> wrote:
    >> Anyway, I think the best practice here would have been to use the map
    >> iterator reference_type instead of writing it myself.

    >
    > Or you could just do a: for(auto& elem: map) std::cout<< elem.first;
    >
    > (But yes, I understand that this solution only works as a substitute
    > for a for_each() that traverses the entire data container, not one that
    > traverses only a subrange, or for a completely different algorithm.)


    Well, if you're using C++11 features...

    for (auto iter = map_var.begin(); iter != map_var.end(); ++iter)
    {
    // yada yada yada

    }
    red floyd, Apr 4, 2012
    #5
  6. On 2012-04-04, Vianney Lançon <> wrote:
    > Le 04/04/2012 14:26, Brice Gagnage a écrit :
    > so you are trying to cast a pair< Key, Type> to a const pair<const Key,
    > Type>&


    Yep, that was the point :) Thanks Mr. Hamster :)

    --
    Brice Gagnage
    Brice Gagnage, Apr 5, 2012
    #6
  7. On 2012-04-04, red floyd <> wrote:
    > On 4/4/2012 9:28 AM, Juha Nieminen wrote:
    >> Brice Gagnage<> wrote:
    >>> Anyway, I think the best practice here would have been to use the map
    >>> iterator reference_type instead of writing it myself.

    >>
    >> Or you could just do a: for(auto& elem: map) std::cout<< elem.first;
    >>
    >> (But yes, I understand that this solution only works as a substitute
    >> for a for_each() that traverses the entire data container, not one that
    >> traverses only a subrange, or for a completely different algorithm.)

    >
    > Well, if you're using C++11 features...
    >
    > for (auto iter = map_var.begin(); iter != map_var.end(); ++iter)
    > {
    > // yada yada yada
    >
    > }


    Thanks for all your answers, I agree that I should use the range-based
    for-loop, but my compiler doesn't support it yet :)

    --
    Brice Gagnage
    Brice Gagnage, Apr 5, 2012
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    408
    red floyd
    Dec 21, 2008
  2. Micha³ 'Khorne' Rzechonek

    C++0x: unique_ptr and std::move

    Micha³ 'Khorne' Rzechonek, Jan 28, 2009, in forum: C++
    Replies:
    7
    Views:
    6,894
  3. Jayden Shui

    Is this a bug of std::unique_ptr?

    Jayden Shui, Dec 16, 2011, in forum: C++
    Replies:
    4
    Views:
    803
  4. Jayden Shui
    Replies:
    2
    Views:
    342
    Jayden Shui
    Dec 16, 2011
  5. Martin Ba
    Replies:
    1
    Views:
    282
    Martin Ba
    Nov 23, 2012
Loading...

Share This Page