在C或C++中,有没有一种方法可以扩展没有继承的类?

pau*_*ons 14 c c++ extension-methods

有没有办法在C和/或C++中实现类别(Objective-C)或扩展方法(C#3.0)等功能?

Pau*_* II 24

C++具有自由函数,但有时扩展方法在将多个函数嵌套在一起时效果更好.看看这个C#代码:

var r = numbers.Where(x => x > 2).Select(x => x * x);
Run Code Online (Sandbox Code Playgroud)

如果我们使用自由函数在C++中编写它,它将如下所示:

auto r = select(where(numbers, [](int x) { return x > 2; }), [](int x) { return x * x; });
Run Code Online (Sandbox Code Playgroud)

这不仅难以阅读,而且难以编写.解决这个问题的常用方法是创建所谓的pipable函数.这些函数是通过重载|管道操作符(实际上是操作符)来创建的.所以上面的代码可以写成这样:

auto r = numbers | where([](int x) { return x > 2; }) | select([](int x) { return x * x; });
Run Code Online (Sandbox Code Playgroud)

这更容易阅读和写作.许多库对范围使用pipable函数,但也可以扩展到其他类.Boost在它的范围库中使用它,pstade 烤箱使用它,而且这个C++ linq库也使用它.

如果您想编写自己的pipable函数,请在此处解释如何执行此操作.但是,其他库提供了功能适配器以使其更容易.Pstade egg有一个pipable适配器,linq提供range_extension适配器以创建至少范围的pipable功能.

使用linq,首先只需将函数创建为函数对象,如下所示:

struct contains_t
{
    template<class Range, class T>
    bool operator()(Range && r, T && x) const
    { return (r | linq::find(x)) != boost::end(r); };
};
Run Code Online (Sandbox Code Playgroud)

然后使用静态初始化初始化函数,如下所示:

range_extension<contains_t> contains = {};
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用你的pipable函数:

if (numbers | contains(5)) printf("We have a 5");
Run Code Online (Sandbox Code Playgroud)


Bil*_*eal 0

关于C#的扩展方法:不直接。C++ 对这些东西的需求较少,因为 C++ 支持自由函数。我从未使用过 Objective-C,所以我无法对此发表评论。