如何将C ++ lambda调整为接收器接口,例如back_inserter等

时间:2011-11-05 07:38:34

标签: c++ lambda adapter

我想知道是否可以在不必定义额外类的情况下,如果lambda可以适合作为接收器。

例如,我们目前可以执行以下操作:

std::vector<int> ilst;

std::copy(ilst.begin(),ilst.end(),std::ostream_iterator<int>(std::cout,"\n"));

如果可能出现以下情况怎么办?显然以下不会 编译atm:

std::copy(ilst.begin(),ilst.end(),
          [](const int& i)
          {
             std::cout << i << "\n"; 
          });

通过定义实现解除引用和函数运算符的函数对象并将lambda作为谓词,我已经能够解决这个问题。

但是我想知道是否有某种C ++巫术可以提供上述内容而不需要提供额外的中间类?

2 个答案:

答案 0 :(得分:9)

如果没有适配器对象,则无法执行此操作。

std::copy接受一个符合标准库输出迭代器要求的输出迭代器。 lambda函数是一个具有operator()的对象,它接受某些参数并返回一个值。这是两种不同的事情。

如果你有一个接受Y的接口,但你有一个X,那么唯一的协调方式是引入一个将X转换为Y的Z。

由于X和Y是对象,因此Z必须是提供Y接口的对象,但在内部将其转换为X.Z通常称为适配器对象。

没有替代方案&#34; C ++ voodoo&#34;这将改变这一点。没有&#34;其他解决方案&#34;。您必须使用某种适配器。无论它是类类型的临时类型还是返回类实例的函数,只能通过适配器对象来解决。


应用于这种特殊情况 - X是lambda,Y是输出迭代器,Z是function_output_iterator

#include <boost/function_output_iterator.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> ilst;
    boost::copy(
        ilst,
        boost::make_function_output_iterator(
            [](int i) { std::cout << i << "\n"; }));
}

答案 1 :(得分:0)

这会做你期望的吗?

std::for_each(ilst.begin(),ilst.end(),
          [](const int& i)
          {
             std::cout << i << "\n"; 
          });

我怀疑这个例子是更复杂的东西的替身,其中for_each不合适。是这样吗?