0

我是boost的新手。这是我的测试代码,

  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 个重载都不能转换所有参数类型

我想知道怎么了?非常感谢。

4

3 回答 3

1

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

第二个问题是标准库成员函数的类型未指定:允许实现者向成员函数添加带有默认参数的额外参数,并且允许他们添加成员函数的额外重载,因此您所做的任何转换都不会便携的。消歧示例假设我们忽略了第二个问题。

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

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

使用 C++0x 函数库,以下工作(如果你用 替换它也应该与 Booststd::一起工作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(); });
于 2010-10-29T03:20:11.103 回答
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);
于 2010-10-29T03:18:02.387 回答
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;
}
于 2010-10-29T04:01:22.280 回答