【问题标题】:Member function template to call a funcion on a data member with arbitrary arguments成员函数模板,用于在具有任意参数的数据成员上调用函数
【发布时间】:2020-02-19 01:52:02
【问题描述】:

我正在研究 C++11 代码库,想知道如何调用传递任意参数的成员类型的任何函数。 请注意,由于我使用的是 C++11,因此无法使用 std::invoke 之类的内容。

我开始在 Outer 类中创建一个函数模板,但我最初的尝试给了我一个编译错误。

#include <iostream>
#include <utility>
#include <type_traits>

struct Inner {
  void bar(int x) {
    std::cout << "Called: x=" << x << std::endl;
  }
};

struct Outer {
  explicit Outer(Inner *i) : b{i} {}
  void foo(int) {}
  Inner* b;

  template <typename Func, typename ... Args>
  void CallInner(Func&& f, Args&& ... args) {
    b->f(std::forward<Args>(args)...);
  }
};


int main() {
  Inner inner{};
  Outer outer(&inner);
  outer.CallInner(&Inner::bar, 5);
}

Try it out yourself

同样,我想保持函数 CallInner 的签名与上述示例代码保持不变。

【问题讨论】:

    标签: c++ c++11 templates variadic-templates


    【解决方案1】:

    由于f 是一个成员函数的指针,因此在调用它之前需要先取消引用:

    (b->*f)(std::forward<Args>(args)...);
    

    【讨论】:

      【解决方案2】:

      在更改签名方面您没有太多选择,因为至少需要一个额外的模板。

      正确的语法稍微复杂一点:

      struct Outer {
        explicit Outer(Inner *i) : b{i} {}
        void foo(int) {}
        Inner* b;
      
          template <typename Ret, typename ...FuncArgs,  typename ... Args>
          void CallInner(Ret (Inner::*f)(FuncArgs...), Args&& ... args) {
              (b->*f)(std::forward<Args>(args)...);
        }
      };
      

      CallInner 的第一个参数必须是方法指针,并且在模板上下文中,它不仅需要通过一组可变参数模板参数 FuncArgs 进行模板化,还需要通过其返回类型 @987654324 进行模板化@。然后,您还需要第二组可变参数模板参数,用于您要转发的参数的转发引用(可能不一定与FuncArgs 相同,因此需要一组单独的可变参数模板类型)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-11
        • 2018-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多