如何将成员函数模板作为模板参数传递?

问题描述 投票:0回答:3

我有一个这样的会员功能:

class Foo
{
public:
  template<typename... Args>
  static void bar(const Args&... args)
  {
    /* code */
  }
};

我想将它作为模板参数传递给这样的成员函数:

class Example
{
public:
  template<typename... Args, typename T> // <- ???
  void doStuff(const Args&... args)
  {
    T(args...);
  }
};

我已经在这里尝试了很多东西,但最有希望的是这个:

class Example
{
public:
  template<typename... Args, typename C, void (C::*F)(Args&...)>
  void doStuff(const Args&... args)
  {
    (C::F)(args...);
  }
};

排错的时候我想可能是因为我把 bar 的函数签名搞错了,所以我把 doStuff 的模板改成这样:

template<typename... Args, typename C, void (C::*F)(const Args&...)>

这似乎没有帮助。

我怀疑是因为我没有定义参数F的模板,但我不知道如何添加它。 或者我可以通过将 lambda 作为属性传递给 doStuff 来一起解决这个问题。不过我还没有尝试过,理想情况下我不想诉诸于此。

编辑2:

这是一个最小的可复制示例:

class Foo
{
public:
  template<typename... Args>
  static void bar(const Args&... args)
  {
    /* code */
  }
};

class Example
{
public:
  template<typename... Args, typename C, void (C::*F)(Args&...)>
  void doStuff(const Args&... args)
  {
    (C::F)(args...);
  }
};

class SomeClass
{
public:
  Example ex {};

  template<typename... Args>
  void someFunc(const Args&... args)
  {
    ex.doStuff<Args..., Foo, &Foo::bar>(args...);
  }
};

int main()
{
  SomeClass sc {};
  sc.someFunc("Some ", "Arguments ", "Here");
  return 0;
}

我知道我知道,我急着问sry

c++ templates function-pointers pointer-to-member
3个回答
0
投票

很多事情都不清楚。例如,为什么要传递一个模板以及用于实例化它的参数,而不是直接传递实例化。但是,我想这是由于简化,你想要的是将静态成员模板作为另一个模板的参数。

据我所知,这是不可能的。至少不是直接的。

你可以做的是使用模板模板参数来传递类型。该模板的静态方法可以转发到

Foo
的静态方法:

#include <iostream>

class Foo
{
public:
  template<typename... Args>
  static void bar(const Args&... args)
  {
  }
};

template <typename ...Args>
struct helper {
    static void bar(const Args&...args){
        Foo::bar(args...);
    }
};


template<template<typename...> typename M,typename...Args>
void doStuff(const Args&... args) {
    M<Args...>::bar(args...);
}


int main() {
    doStuff<helper,int>(42);
}

根据您的实际需要,可以在类型上对 helper 进行参数化,因此您也可以将它用于具有

bar
静态方法的其他类型。但是,对于具有不同名称的静态方法的其他类型,我们回到原点,您将需要另一个助手。

如果你只是想将一个可调用对象传递给

doStuff
也许它不必比这更复杂:

 template <typename F, typename Args...>
 void doStuff(F f,const Args&...args) { F(args...); }
 // (no perfect forwarding as in your code and in the code above)

 int main() { 
      doStuff([](int a) { Foo::bar(a); },42);
 }

0
投票

不幸的是,我没有太多时间,但这里有一个关于如何将成员函数指针传递到函数模板以选择“回调”来处理数据的快速镜头。

#include <iostream>
#include <utility>

struct A
{
    template<class ... Q>
    void x(Q&&... q)    
    {
        std::cout << "A::x\n";
    }
    template<class ... R>
    void y(R&&... r)    
    {
        std::cout << "A::y\n";
    }
    template<class F, class ... W>
    void do_stuff(F&& f, W&&... w)  
    {
        std::cout << "A::do_stuff\n";
        (this->*f)(std::forward<W>(w)...);
    }
};

class B
{
public:

  A a{};

  template<typename... Args>
  void bar(Args&&... args)
  {
    a.do_stuff(&A::x<Args...>, std::forward<Args>(args)...);
    a.do_stuff(&A::y<Args...>, std::forward<Args>(args)...);
  }
};

int main()
{
  B b{};
  b.bar(1, "yes");
}

0
投票

我们不必对静态成员函数使用

(Classtype::*)()
语法。静态成员函数被视为普通的自由函数。下面是工作示例,我在其中展示了如何实现您想要的:

class Foo
{
public:
  template<typename... Args>
  static void bar(const Args&... args)
  {
    /* code */ 
  }
};

class Example
{
public:
  
 
    template< typename... Param,typename Ret, typename... Args>  
    //no need to use any class type here as we have static member function which is treated as ordinary free function
    void doStuff(Ret (*ptrFunc)(const Param&... param),const Args&... args)

    {

    }
};

class SomeThing
{
public:
  Example ex {};

  template<typename... Args>
  void someFunc(const Args&... args)
  {
    ex.doStuff(&Foo::bar<Args...>,args...);    
  }
};

int main()
{
  SomeThing sc {};
  sc.someFunc("Some ", "Arguments ", "Here"); 
  
  return 0;

}
© www.soinside.com 2019 - 2024. All rights reserved.