2011-05-21 1 views
3

Что случилось с этим:станд :: Еогеасп с усилением :: связать

template <typename T> 
std::list<T> & operator+=(std::list<T> & first, std::list<T> const& second) 
{ 
    std::for_each(second.begin(), second.end(), boost::bind(&std::list<T>::push_back, first, _1)); 

    return first; 
} 

Он отлично компилируется, но не работает.

+2

Что означает «не работает»? – Mat

+1

Это не отвечает на ваш вопрос, но если ваш код действительно это надуманный (в отличие от примера, урезанного для вопроса, я имею в виду), что не так с 'std :: copy' с' std :: back_inserter'? –

+0

В дополнение к Tomalak стандартная идиома выполнения этой задачи в C++: 'std :: copy (second.begin(), second.end(), std :: back_inserter (первая));' –

ответ

6

Чтобы передать аргумент/объект по ссылке, вам необходимо использовать boost::ref, иначе bind создает внутреннюю копию.

std::for_each(
    second.begin(), second.end(), 
    boost::bind(&std::list<T>::push_back, boost::ref(first), _1) 
); 
+0

Конечно, t измените тот факт, что '& std :: list :: push_back' имеет неуказанное поведение, поэтому оно все еще может или не может быть скомпилировано (и на самом деле оно гарантировано ** не ** на любом компиляторе с поддержкой ссылки rvalue) ... – ildjarn

+0

Спасибо, Cat, это работает. @ildjarn, не могли бы вы ссылаться на дополнительную информацию о why & std :: list :: push_back имел бы неуказанное поведение? – Heptic

+0

@Heptic: [Использование std :: tr1 :: bind с std :: vector :: push_back] (http://stackoverflow.com/questions/6007563/using-stdtr1bind-with-stdvectorpush-back/6008660#6008660) – ildjarn

3
std::list<T> ls; 
std::list<T> ls0; 
// ... 
ls.insert(ls.end(), ls0.begin(), ls0.end()); 
6

Обратите внимание, что в то время как решение Cat Plus Plus была бы работать для вас, поощрял способ сделать такие вещи в C++ 03 (до появления, если лямбды в предстоящем стандартной версии) является использование стандартные библиотечные алгоритмы и функторы. К сожалению, в некоторых случаях они довольно запутаны, но в этом случае я думаю, что они дают более четкий код:

std::copy(second.begin(), second.end(), std::back_inserter(first)); 
+0

«* Обратите внимание, что хотя решение Cat Plus Plus будет работать для вас *« Абсолютно нет; этот код откажется компилировать любой компилятор, выпущенный за последний год или два. – ildjarn

+0

Ну, это сработало для него. :) –

+0

@BoazYaniv: Пока он не обновит свой компилятор. ; -] – ildjarn