代码之家  ›  专栏  ›  技术社区  ›  aep

成员函数模板,用于调用具有任意参数的数据成员上的函数

  •  0
  • aep  · 技术社区  · 6 年前

    我正在研究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

    2 回复  |  直到 6 年前
        1
  •  1
  •   David G    6 年前

    自从 f

    (b->*f)(std::forward<Args>(args)...);
    
        2
  •  0
  •   Sam Varshavchik    6 年前

    对于更改签名,您没有太多选择,因为至少需要一个附加模板。

    正确的语法要复杂一点:

    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 ,但也是它的返回类型, Ret 函数 ,因此需要一组单独的可变模板类型)。