увеличить лямбда с помощью вектора общих указателей

Ниже приведен слегка измененный код из одного хорошего примера, как копировать значения из одного вектора строк в другой вектор объектов. (см.: другой алгоритм копирования)

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

using boost::shared_ptr;
using boost::make_shared;
using namespace boost::lambda;

class Object
{
public:
    std::string Name;

    Object(const std::string& Name_ = "")
        : Name(Name_)
    {
    }
};

int main()
{
    //std::vector<Object> objects(3, Object());
    std::vector<shared_ptr<Object> > objects(3, make_shared<Object>());

    std::vector<std::string> names;
    names.push_back("Alpha");
    names.push_back("Beta");
    names.push_back("Gamma");
    std::vector<std::string>::const_iterator names_it;
    names_it = static_cast<const std::vector<std::string>&>(names).begin();

    //std::for_each(objects.begin(), objects.end(), bind(&Object::Name, _1) = *var(names_it)++);
    std::for_each(objects.begin(), objects.end(), bind(&Object::Name, *_1) = *var(names_it)++);

    //std::vector<Object>::iterator it, end = objects.end();
    std::vector<shared_ptr<Object> >::iterator it, end = objects.end();
    for (it = objects.begin(); it != end; ++it) {
        //std::cout << it->Name << std::endl;
        std::cout << (*it)->Name << std::endl;
    }

    return EXIT_SUCCESS;
}

В этом случае я использую динамически размещаемые объекты, и поскольку boost::lambda::bind не может обрабатывать такие изменения, как это делает boost::bind, мне нужно разыменовать заполнитель для компиляции:

std::for_each(objects.begin(), objects.end(), bind(&Object::Name, *_1) = *var(names_it)++);

Но тогда на выходе у меня есть:

Gamma
Gamma
Gamma

Каково ваше объяснение?


person sigidagi    schedule 07.10.2011    source источник
comment
Вы должны знать, что с последним выпуском Boost.Phoenix v3 Boost.Lambda теперь официально объявлено устаревшим. Вместо этого используйте Phoenix для нового кода. :-]   -  person ildjarn    schedule 07.10.2011


Ответы (1)


std::vector<shared_ptr<Object> > objects(3, make_shared<Object>());

Это эквивалентно выполнению:

shared_ptr<Object> object = make_shared<Object>();
std::vector<shared_ptr<Object> > objects(3, object);

Конструктор вектора создаст 3 копии этого указателя object, и все они будут ссылаться на один и тот же и уникальный Object (то есть *object). Заполните вектор отдельными указателями, каждый из которых инициализируется своим собственным Object.

person Luc Danton    schedule 07.10.2011
comment
Полностью отказался от «решения» Boost.Lambda. Я рекомендую Boost.Phoenix (v3), если вы можете переключиться. - person Luc Danton; 07.10.2011