lambda 绑定问题?

发布于 2024-09-29 20:44:06 字数 629 浏览 0 评论 0原文

我是一个有提升的新手。这是我的测试代码,

  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);

构建项目并产生错误:

error C2665: 'boost::lambda::function_adaptor::apply' : 两个重载都不能转换所有参数类型

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

I am a new beginner with boost. And here is my test code,

  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);

build the project and yield an error:

error C2665: 'boost::lambda::function_adaptor::apply' : none of the 2 overloads could convert all the argument types

I wonder what's wrong? Really appreciate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泛泛之交 2024-10-06 20:44:06

第一个问题是 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(); });

The first problem is that std::vector::push_back is an overloaded function in C++0x (there is an overload with an lvalue reference parameter and an overload with an rvalue reference parameter).

The second problem is that the types of Standard Library member functions are unspecified: implementers are permitted to add extra parameters with default arguments to member functions, and they are permitted to add additional overloads of member functions, so any casting that you do would not be portable. The disambiguation example assumes that we ignore this second problem.

You will need to cast the pointer-to-member-function to the correct type, otherwise this won't work with a C++0x library implementation (the pointer-to-member-function will be ambiguous). You'll need:

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

Using the C++0x functional library, the following works (it should work with Boost as well if you replace std:: with boost::; I just can't test that):

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)));

Note that this is a real mess and it's much clearer just to use a for loop:

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

Or, if you have a compiler that supports lambda expressions:

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

Or, for more fun:

std::transform(strings.begin(), strings.end(), std::back_inserter(sizes),
               [](const std::string& s) { return s.size(); });
情徒 2024-10-06 20:44:06
  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);
  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);
扎心 2024-10-06 20:44:06

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

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;
}

Or you can create your own function object:

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

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

Then use it (note the ostream_iterator and copy replacing another 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文