如何适配C++到接收器接口的 lambda,例如 back_inserter 等

发布于 2024-12-13 13:53:07 字数 535 浏览 3 评论 0原文

我想知道是否可以在不必定义额外的类的情况下,是否可以将 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++ voodoo 可以实现上述功能,而不需要提供额外的中间类?

I would like to know if its possible without having to define an extra class, if a lambda can be adapted to act as a sink.

For example we currently can do the following:

std::vector<int> ilst;

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

What if something like the following could be possible? obviously the following wont
compile atm:

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

I've been able to get around this problem, by defining a function object that implements dereference and function operators and takes a lambda as a predicate.

However I was wondering if there is some kind of C++ voodoo that will allow for the above without the need for an extra intermediary class to be provided?

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

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

发布评论

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

评论(2

咽泪装欢 2024-12-20 13:53:07

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

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

如果您有一个接受 Y 的接口,但有一个 X,则协调此问题的唯一方法是引入一个将 X 转换为 Y 的 Z。

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

没有替代的“C++ 巫毒”可以改变这一点。没有“其他解决方案”。您必须使用某种适配器。无论是类类型的临时变量还是返回类实例的函数,都只能通过适配器对象来解决。


应用于这种特殊情况 - 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"; }));
}

You cannot do this without an adapter object.

std::copy takes an output iterator which conforms to the standard library output iterator requirements. A lambda function is an object that has an operator() that takes certain arguments and returns a value. These are two different kinds of things.

If you have an interface that takes Y, but you have a X, the only way to reconcile this is to introduce a Z that converts X into Y.

And since X and Y are objects, Z must therefore be an object that provides the Y interface, but internally converts it into an X. Z is commonly called an adapter object.

There is no alternative "C++ voodoo" that's going to change this. There is no "other solution". You must use some kind of adapter. Whether it's a temporary of a class type or a function that returns an instance of a class, this can only be resolved with an adapter object.


Applied to this particular situation - X is a lambda, Y is an output iterator, and Z is a 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"; }));
}
皓月长歌 2024-12-20 13:53:07

这会达到你的预期吗?

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

我怀疑这个例子是更复杂的事情的替代品,其中 for_each 不适合。是这样吗?

Would this do what you expect?

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

I suspect that this example is a stand-in for something more complicated, where for_each is unsuitable. Is this so?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文