c++ - 将函数传递给方法原型(prototype)

标签 c++ templates function-pointers pointer-to-member

假设我有一个模板:

template <typename T>
class foo{
    void (T::bar*)(int);
public:
    void setMethod(void (T::*)(int) f)
};

有没有办法在这个模板中使用非成员函数?

我试过:

  • foo<void>().setMethod(&func);
  • foo<nullptr_t>().setMethod(&func);

最佳答案

不,这不可能。

有用解决方法的确切性质取决于问题的性质,但很可能涉及 std::functionstd::bind (或 lambda)。一般而言,诀窍通常是重写 foo以这样一种方式,它不必关心绑定(bind)到它的函数类型(这就是 std::function 的用途)。

可以这样做的一种方法是

template <typename T>
class foo{
public:
  // Here we do not care about the type of function we're binding
  template<typename Func>
  void  setMethod(Func f) { func_ = f; }

  void callMethod(T &obj) { func_(obj); }

private:
  // only about its signature
  std::function<void(T&)> func_;
};

给定一个类型

struct A {
  void foo();
  void bar(int);
};

还有一个函数

void qux(A &);

以后可以做任何

Foo<A> f;

f.setMethod(&A::foo);
f.setMethod(qux);
f.setMethod(std::bind(&A::bar, std::placeholders::_1, 2));
f.setMethod([](A &obj) { obj.foo(); });

或者确实调用setMethod任何有 operator() 的东西接受A& .

如果需要 Liskov 替换(OP 就是这种情况),这将不起作用,因为 foo不能根据公共(public)基类中的模板参数提供接口(interface)。那么剩下两个选项:

  • 如果要调用该函数的对象可以与该函数同时绑定(bind),则可以生成foo。一个类,让它存储一个std::function<void()>并推一个std::bind(&SomeClass::memberfunction, SomeObject)
  • 否则,如果没有非常邪恶的 hackery,您将获得的最好结果就是将自己限制在一个共同的基类中,该基类本来是 Tfoo 的参数.

如果您的需求超出此范围,您就是在试图突破 C++ 类型系统的限制,您应该重新考虑您的设计。

关于c++ - 将函数传递给方法原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27624961/

相关文章:

c - 将额外数据存储在 c 函数指针中

c++ - 我将如何编辑此代码以使最小堆成为可能?

c++ - 理解和解析来自 gcc 的警告

c++ - 如何将具有不同参数的 std::function 传递给同一函数

c++ - 为什么标准不将模板构造函数视为复制构造函数?

c - 将函数指针名称传递给 C 预处理器

c++ - 为什么我需要一个前向迭代器来实现我定制的 std::search

c++ - 使用 json 库创建 json 字符串

c++ - 添加具有模板特化的方法

c++ - 在对函数指针进行 typedef 时 * 是强制性的吗?