C++ std::foreach和boost::bind

C++ std::foreach和boost::bind,c++,stl,boost-bind,C++,Stl,Boost Bind,这有什么问题吗 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)

这有什么问题吗

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;
}
模板
标准::列表和运算符+=(标准::列表和第一个,标准::列表常量和第二个)
{
std::for_each(second.begin(),second.end(),boost::bind(&std::list::push_back,first,_1));
先返回;
}

它编译得很好,但不起作用。

您需要使用
boost::ref
通过引用传递参数/对象,否则bind将创建一个内部副本

std::for_each(
    second.begin(), second.end(),
    boost::bind(&std::list<T>::push_back, boost::ref(first), _1)
);
std::每个(
second.begin(),second.end(),
boost::bind(&std::list::push_back,boost::ref(第一个),_1)
);
std::list ls;
std::列表ls0;
// ...
insert(ls.end(),ls0.begin(),ls0.end());

请注意,虽然Cat Plus的解决方案适合您,但在C++03中(如果lambdas在即将发布的标准版本中出现,则在出现之前)鼓励您使用标准库算法和函子。不幸的是,在某些情况下,它们自己会变得非常复杂,但在这种情况下,我认为它们会产生更清晰的代码:

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

“不起作用”到底是什么意思?这并不能回答你的问题,但如果你的代码真的是这么做作的(我的意思是,与这个问题的示例相反),用
std::copy
std::back\u inserter
来补充Tomalak有什么错,在C++中做这件事的标准习惯用法是:<代码> STD::复制(第二个开始),第二个,(),STD::BuffixEnter(第一个);代码>“请注意,尽管Cat Plus的解决方案适合您”,但绝对不行;该代码将拒绝在过去一两年中发布的任何编译器上编译。@BoazYaniv:直到他升级他的编译器为止。.-]#包括算法和迭代器,然后使用
std::copy()
back\u inserter()
这是太多无缘无故的工作了。实际上,当标准提供成员函数时,你应该使用它,而不是通用算法。@wilhelmtell:虽然我同意
list::insert
在这里更合适,什么是真正的C++代码没有代码>算法<代码> >代码>迭代器< /代码>已经包含?@威廉:在这个例子中,我承认使用插入()更可读,但是,
std::copy
在许多情况下非常有用,因为您不想固定在单个容器上。当然,这不会改变
&std::list::push_back
具有未指定行为的事实,因此这仍然可能编译,也可能不会编译(事实上,保证不会在任何具有右值引用支持的编译器上编译)…谢谢猫,这很有效@ildjarn,你能链接到更多关于为什么&std::list::push_back会有未指定的行为的信息吗?@Heptic:@Heptic:不过,要做你想做的事情,最好的方法是back_inserter,把这个答案更像是“为什么我的绑定在不同的对象上运行,即使我有引用”。
std::copy(second.begin(), second.end(), std::back_inserter(first));