lambda绑定问题?

时间:2010-10-29 03:09:26

标签: c++ boost bind boost-lambda

我是一名新的助推器。这是我的测试代码,

  using namespace boost::lambda;
  std::vector<std::string> strings; 
  strings.push_back("Boost"); 
  strings.push_back("C++"); 
  strings.push_back("Libraries"); 

  std::vector<int> sizes; 

  std::for_each(
   strings.begin(),
   strings.end(),
   bind(
  &std::vector<int>::push_back,
  sizes,
  bind<std::size_t>(&std::string::size, _1)));

  std::for_each(sizes.begin(), sizes.end(), var(std::cout)<<_1);

构建项目并产生错误:

错误C2665:'boost :: lambda :: function_adaptor :: apply':2个重载中没有一个可以转换所有参数类型

我想知道出了什么问题?真的很感激。

3 个答案:

答案 0 :(得分:1)

第一个问题是std::vector::push_back是C ++ 0x中的重载函数(带有左值引用参数的重载和带有右值引用参数的重载)。

第二个问题是未指定标准库成员函数的类型:允许实现者使用默认参数向成员函数添加额外参数,并且允许它们添加成员函数的其他重载,因此您执行任何转换不会是便携式的。消除歧义的例子假设我们忽略了第二个问题。

您需要将指向成员函数的指针强制转换为正确的类型,否则这将不适用于C ++ 0x库实现(指向成员函数的指针将是不明确的)。你需要:

(void (std::vector<int>::*)(const int&))&std::vector<int>::push_back

使用C ++ 0x函数库,以下工作(如果将std::替换为boost::,它也可以与Boost一起使用;我无法测试它):

std::for_each(
    strings.begin(),
    strings.end(),
    std::bind(
       (void (std::vector<int>::*)(const int&))&std::vector<int>::push_back,
       std::ref(sizes),
       std::bind(&std::string::size, std::placeholders::_1)));

请注意,这是一个真正的混乱,使用for循环更清楚:

for(std::vector<int>::const_iterator i(strings.begin()); i != strings.end(); ++i)
{
    sizes.push_back(i->size());
}

或者,如果您有一个支持lambda表达式的编译器:

std::for_each(strings.begin(), strings.end(), 
              [&](const std::string& s) { sizes.push_back(s.size()); });

或者,为了更多的乐趣:

std::transform(strings.begin(), strings.end(), std::back_inserter(sizes),
               [](const std::string& s) { return s.size(); });

答案 1 :(得分:0)

  namespace lambda = boost::lambda;
  std::vector<std::string> strings; 
  strings.push_back("Boost"); 
  strings.push_back("C++"); 
  strings.push_back("Libraries"); 

  std::vector<int> sizes; 

  std::for_each(
   strings.begin(),
   strings.end(),
   bind(
  &std::vector<int>::push_back,
  sizes,
  bind<std::size_t>(&std::string::size, _1)));

  std::for_each(sizes.begin(), sizes.end(), lambda::var(std::cout)<< lambda::_1);

答案 2 :(得分:0)

或者您可以创建自己的函数对象:

template <typename T>
struct c_inserter
{
    T& c;

    c_inserter(T& c) : c(c) {}
    void operator()(string& v) { c.push_back(v.size()); }
};

然后使用它(注意ostream_iteratorcopy替换另一个lambda):

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

#include <boost/lambda/lambda.hpp>

int main() 
{
    std::vector<std::string> strings;
    strings.push_back("Boost");
    strings.push_back("C++");
    strings.push_back("Libraries");

    std::vector<int> sizes;

    std::for_each(
            strings.begin(),
            strings.end(),
            c_inserter< vector<int> >(sizes));

    copy(sizes.begin(), sizes.end(), ostream_iterator<int>(cout,":"));
    cout << endl;
}