gpt4 book ai didi

c++ - 在C++11或更高版本中,有没有办法通过lambda实现单方法纯虚C++接口(interface)?

转载 作者:可可西里 更新时间:2023-11-01 18:10:00 25 4
gpt4 key购买 nike

我有一个用 C++ 98 编写的大型 C++ 库,它大量使用 C++ 接口(interface)(准确地说,只有纯虚函数的 C++ 类)来处理事件。现在看到我的代码是由 C++11/14 编译器编译的,我在想是否可以通过使用 C++11 lambda 替换接口(interface)实现来减少样板代码。

在我的库中,有一些 C++ 接口(interface)只有一个方法,例如,我们用来定义一个简单任务的以下接口(interface):

class SimpleTask
{
public:
virtual void run() = NULL;
};

我的意图是使用 C++ lambda 来替换旧的单一方法接口(interface)实现代码,如下所示:

void myFunction()
{
...

class MySimpleTask : SimpleTask //An inline class to implement the iterface
{
public:
void run()
{
//Do somthing for this task
...
delete this; //Finally, destroy the instance
}
};
MySimpleTask * myThreadTask = new MySimpleTask();
Thread myThread(L"MyTestingThread", myThreadTask);
myThread.start();

...
}

在 Java 8 中,we can use Java lambda to implement a single-method interface编写代码比使用匿名类更简洁。我在 C++11 中做了一些研究,发现没有类似的东西。

由于我的库的事件处理代码是以面向对象的模式设计的,而不是以函数式编码风格设计的,有没有办法使用 lambda 来帮助减少那些单一方法接口(interface)实现代码?

最佳答案

您可以创建一个包装器,例如:

class SimpleTask {
public:
virtual void run() = 0;
};

// This class wraps a lambda (or any callable) and implement the run()
// method by simply calling the callable.
template <class T>
class LambdaSimpleTask: public SimpleTask {
T t;

public:
LambdaSimpleTask(T t) : t(std::move(t)) { }

virtual void run() {
t();
}
};


template <class T>
auto makeSimpleTask(T &&t) {
// I am returning a dynamically allocated object following your example,
// but I would rather return a statically allocated one.
return new LambdaSimpleTask<std::decay_t<T>>{std::forward<T>(t)};
}

然后创建任务:

auto task = makeSimpleTask([]() { });
Thread myThread(L"MyTestingThread", task);

请注意,您仍然需要为每个界面设置一个包装器和一个makeXXX 函数。使用 C++17 及更高版本,您可以通过使用类模板参数推导来摆脱 makeXXX 函数。摆脱包装器是不可能的,但您可以通过在宏中封装一些东西来减少样板代码。


这是一个示例宏(不完美),可用于减少样板代码:

#define WRAPPER_FOR(C, M, ...)                       \
template <class T> \
class Lambda##C: public C { \
T t; \
public: \
Lambda##C(T t) : t(std::move(t)) { } \
virtual M { return t(__VA_ARGS__); } \
}; \
template <class T> auto make##C(T &&t) { \
return Lambda##C<std::decay_t<T>>{std::forward<T>(t)}; }

然后:

class SimpleTask {
public:
virtual void run() = 0;
};

class ComplexTask {
public:
virtual int run(int, double) = 0;
};

WRAPPER_FOR(SimpleTask, void run());
WRAPPER_FOR(ComplexTask, int run(int a, double b), a, b);

关于c++ - 在C++11或更高版本中,有没有办法通过lambda实现单方法纯虚C++接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56259644/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com