用 shared_from_this 生成仿函数
Generate functor with shared_from_this
我想从继承自 enable_shared_from_this 的 class A 创建一个仿函数,它适用于像这样的 class:
class A: public std::enable_shared_from_this<A> {
...
}
我想要一个看起来像这样的成员函数(错误代码):
template <typename Args...>
std::function<void(Args ...)> functor_from_this(void (A::*method)(Args...)) {
return std::bind(method, shared_from_this());
}
上面的代码产生了几个错误,从 warning C4180: qualifier applied to function type has no meaning; ignored
开始,这让我怀疑我的处理方式有误。我该如何实现这样的目标?
(a) 将 Args... 绑定到仿函数的额外学分,因此我得到了一个签名为 void fn()
的函数,以及 (b) 在通用 class 继承自 enable_shared_from_this<T>
.
嗯,对于 C++14,解决方案是 easy enough to write。只需放弃 std::bind
和 return lambda 即可:
#include <memory>
#include <iostream>
#include <functional>
struct A: std::enable_shared_from_this<A> {
template <typename... Args>
std::function<void(Args...)> functor_from_this(void (A::*method)(Args...)) {
return [=, obj = shared_from_this()](Args... args) {
((*obj).*method)(args...);
};
}
void foo(int) { std::cout << "foo" << '\n'; }
void bar() { std::cout << "bar" << '\n'; }
};
int main()
{
auto a = std::make_shared<A>();
auto f = a->functor_from_this(&A::foo);
auto b = a->functor_from_this(&A::bar);
f(1);
b();
}
对于 Jarod42 在评论中指出的 C++11,使用更简单的中间变量:
#include <memory>
#include <iostream>
#include <functional>
struct A: std::enable_shared_from_this<A> {
template <typename... Args>
std::function<void(Args...)> functor_from_this(void (A::*method)(Args...)) {
auto obj = shared_from_this();
return [=](Args... args) {
((*obj).*method)(args...);
};
}
void foo(int) { std::cout << "foo" << '\n'; }
void bar() { std::cout << "bar" << '\n'; }
};
int main()
{
auto a = std::make_shared<A>();
auto f = a->functor_from_this(&A::foo);
auto b = a->functor_from_this(&A::bar);
f(1);
b();
}
为了加分 (B),这是我根据 StoryTeller 和 Jarod 的回答找到的解决方案:
#include <memory>
#include <iostream>
#include <functional>
template <class T>
class enable_functor_from_this: public std::enable_shared_from_this<T> {
public:
template <typename... Args>
decltype(auto) functor_from_this(void (T::*method)(Args...)) {
auto obj = this->shared_from_this();
return [=](Args... args) {
((*obj).*method)(args...);
};
}
};
struct A: enable_functor_from_this<A> {
void foo(int) { std::cout << "foo" << '\n'; }
void bar() { std::cout << "bar" << '\n'; }
};
int main()
{
auto a = std::make_shared<A>();
auto f = a->functor_from_this(&A::foo);
auto b = a->functor_from_this(&A::bar);
f(1);
b();
}
我想从继承自 enable_shared_from_this 的 class A 创建一个仿函数,它适用于像这样的 class:
class A: public std::enable_shared_from_this<A> {
...
}
我想要一个看起来像这样的成员函数(错误代码):
template <typename Args...>
std::function<void(Args ...)> functor_from_this(void (A::*method)(Args...)) {
return std::bind(method, shared_from_this());
}
上面的代码产生了几个错误,从 warning C4180: qualifier applied to function type has no meaning; ignored
开始,这让我怀疑我的处理方式有误。我该如何实现这样的目标?
(a) 将 Args... 绑定到仿函数的额外学分,因此我得到了一个签名为 void fn()
的函数,以及 (b) 在通用 class 继承自 enable_shared_from_this<T>
.
嗯,对于 C++14,解决方案是 easy enough to write。只需放弃 std::bind
和 return lambda 即可:
#include <memory>
#include <iostream>
#include <functional>
struct A: std::enable_shared_from_this<A> {
template <typename... Args>
std::function<void(Args...)> functor_from_this(void (A::*method)(Args...)) {
return [=, obj = shared_from_this()](Args... args) {
((*obj).*method)(args...);
};
}
void foo(int) { std::cout << "foo" << '\n'; }
void bar() { std::cout << "bar" << '\n'; }
};
int main()
{
auto a = std::make_shared<A>();
auto f = a->functor_from_this(&A::foo);
auto b = a->functor_from_this(&A::bar);
f(1);
b();
}
对于 Jarod42 在评论中指出的 C++11,使用更简单的中间变量:
#include <memory>
#include <iostream>
#include <functional>
struct A: std::enable_shared_from_this<A> {
template <typename... Args>
std::function<void(Args...)> functor_from_this(void (A::*method)(Args...)) {
auto obj = shared_from_this();
return [=](Args... args) {
((*obj).*method)(args...);
};
}
void foo(int) { std::cout << "foo" << '\n'; }
void bar() { std::cout << "bar" << '\n'; }
};
int main()
{
auto a = std::make_shared<A>();
auto f = a->functor_from_this(&A::foo);
auto b = a->functor_from_this(&A::bar);
f(1);
b();
}
为了加分 (B),这是我根据 StoryTeller 和 Jarod 的回答找到的解决方案:
#include <memory>
#include <iostream>
#include <functional>
template <class T>
class enable_functor_from_this: public std::enable_shared_from_this<T> {
public:
template <typename... Args>
decltype(auto) functor_from_this(void (T::*method)(Args...)) {
auto obj = this->shared_from_this();
return [=](Args... args) {
((*obj).*method)(args...);
};
}
};
struct A: enable_functor_from_this<A> {
void foo(int) { std::cout << "foo" << '\n'; }
void bar() { std::cout << "bar" << '\n'; }
};
int main()
{
auto a = std::make_shared<A>();
auto f = a->functor_from_this(&A::foo);
auto b = a->functor_from_this(&A::bar);
f(1);
b();
}