【问题标题】:boost::bind to concatenate strings in std::transformboost::bind 以连接 std::transform 中的字符串
【发布时间】:2013-08-08 12:17:39
【问题描述】:

我正在尝试在 std::transform 中使用 boost::bind 连接两个字符串

假设我的类有两种方法来获取两个字符串(第一个和第二个),并且 conatiner 是字符串的向量,我试图做如下

struct Myclass
{
   std::string getFirstString() {return string1}
   std::string getSecondString() {return string2}

   private:
     std::string string1;
     std::string string2;
}

Myclass myObj;

std::vector<string > newVec;
std::vector<myObj> oldVec;
std::transform (oldVec.begin(), oldVec.end(), std::back_inserter(newVec), boost::bind(&std::string::append,boost::bind(&getFirstString,  _1),boost::bind(&getSecondString, _1 ) ) ); 

但是,我收到错误提示

error: cannot call member function 'virtual const getSecondString() ' without object

我在这里错过了什么?

【问题讨论】:

  • 能否贴出oldVec、newVec、getSecondString、...的声明
  • 还有getFirstString
  • 你为什么不能在这里使用for循环?

标签: c++ boost boost-bind


【解决方案1】:

你有两个问题。

首先是您错误地获取了成员函数的地址。您始终必须指定类,即boost::bind(&amp;Myclass::getFirstString, _1)

第二个是您尝试绑定std::string::append,这会修改它所调用的对象。你真的想要operator +。由于您不能直接绑定,请改用std::plus&lt;std::string&gt;。所以它应该是这样的:

std::transform(oldVec.begin(), oldVec.end(),
               std::back_inserter(newVec),
               boost::bind(std::plus<std::string>(),
                           boost::bind(&Myclass::getFirstString, _1),
                           boost::bind(&Myclass::getSecondString, _1)
                          )
              );

或者您可以改用 Boost.Lambda。当您使用它时,使用 Boost.Range,它很棒。

namespace rg = boost::range;
namespace ll = boost::lambda;
rg::transform(oldVec, std::back_inserter(newVec),
              ll::bind(&Myclass::getFirstString, ll::_1) +
                  ll::bind(&Myclass::getSecondString, ll::_1));

【讨论】:

  • 优秀。每次我认为我知道如何使用 boost::bind 时,我都会被打败。另外,找到了这个 boost::function<:string std::string> f = boost::bind(&std::string::append, _1, _2);
  • 停止使用append。它不会做你想做的事。它会修改您调用它的字符串。将绑定放入 boost::function 以按值获取字符串甚至可以编译,这已经够糟糕了——我不想猜测它到底做了什么。
【解决方案2】:

如果您正在寻找一种时尚的方式(一行代码)来解决您的问题,您可以使用 for_each 和 lambdas 来做到这一点:

std::for_each(oldVec.begin(), oldVec.end(), [&newVec](Myclass& mc) -> void { newVec.push_back(mc.getFirstString() + mc.getSecondString()); });

【讨论】:

  • 是的。任何使用boost的东西。我还没有访问 C++11 的权限。
【解决方案3】:

使用您对第一个答案的评论,也许您可​​以使用 Boost.Foreach:

#include <boost/foreach.hpp>

BOOST_FOREACH(Myclass const& it, oldVec) {
  newVec.push_back(it.getFirstString() + it.getSecondString());
}

顺便说一句,您的问题写得不好,所以我可以假设您实际上是在向量中存储了Myclass副本

【讨论】:

  • 您可能想用 std::string 替换 auto,或者它仍然是 C++11。
  • 如果你可以使用auto,那么你就不需要BOOST_FOREACH了!
  • @justsomebody,我同意这个问题本来可以写得更好。对不起,我认为一些事情是理所当然的。
猜你喜欢
  • 2020-08-03
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多