【问题标题】:std::foreach with boost::bindstd::foreach 与 boost::bind
【发布时间】:2011-05-21 18:23:38
【问题描述】:

这是怎么回事:

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::copy 有什么问题std::back_inserter?
  • 为了补充 Tomalak,在 c++ 中做这件事的标准习惯用法是:std::copy(second.begin(), second.end(), std::back_inserter(first));

标签: c++ stl boost-bind


【解决方案1】:

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

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

【讨论】:

  • 当然,这并没有改变&amp;std::list&lt;T&gt;::push_back 具有未指定行为的事实,因此这仍然可能编译也可能不编译(实际上保证在任何编译器上带有右值引用支持)...
  • 谢谢猫,这行得通。 @ildjarn,您能否链接到有关为什么 &std::list::push_back 会有未指定行为的更多信息?
  • @Heptic:不过,做你想做的最好的方法是 back_inserter,把这个答案更多地当作一个通用的解决方案来解决“为什么我的绑定在不同的对象上运行,即使我有参考”。
【解决方案2】:

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

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

【讨论】:

  • "请注意,虽然 Cat Plus Plus 的解决方案对您有用" 绝对不是;该代码将拒绝在过去一两年发布的任何编译器上编译。
  • @BoazYaniv :直到他升级他的编译器。 ;-]
  • #include 算法和迭代器然后在这里使用std::copy()back_inserter() 无缘无故地工作太多了,imo。实际上,当标准提供成员函数时,您应该使用它而不是通用算法。
  • @wilhelmtell :虽然我同意list&lt;&gt;::insert 在这里更合适,但哪些真正的C++ 代码没有包含algorithmiterator
  • @wilhelmtell:在这种情况下是一个列表,我承认使用 insert() 更具可读性,但 std::copy 在许多你不想要的情况下很有用固定在一个容器上。
【解决方案3】:
std::list<T> ls;
std::list<T> ls0;
// ...
ls.insert(ls.end(), ls0.begin(), ls0.end());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 2023-04-07
    • 2012-02-13
    • 2012-05-20
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多