pau*_*ons 8 c++ extension-methods class
有没有办法向类添加新方法,而不修改原始类定义(即包含类和相应的.h文件的编译.lib),如C#的类扩展方法?
Gle*_*len 11
不,你不能用C++做到这一点.
如果你想要达到这样的目的,你有两个选择,
我更喜欢代表团的做法.
在 C++ 中,您可以使用自由函数,但有时,当您将许多函数嵌套在一起时,扩展方法会更有效。看一下这段 C# 代码:
var r = numbers.Where(x => x > 2).Select(x => x * x);
Run Code Online (Sandbox Code Playgroud)
如果我们使用 free 函数在 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 在他们的range库中使用它,pstade oven使用它,这个 C++ linq库也使用它。
如果您想编写自己的 pipable 函数,请在此处boost 解释如何执行此操作。然而,其他库提供了函数适配器以使其更容易。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)