Typ wskaźnika na funkcję w szablonie

0

Witam
Da się w jakiś sposób przekazać typ do szablonu tak, że ten typ musi być wskaźnikiem na funkcję i tak, żeby potem można było wyodrębnić typ listy argumentów tego wskaźnika na funkcję?
Wiem, że można po prostu tak:

template<typename FunctionType, typename ...FunctionArgs>
class A{
public:
	void func(FunctionType f, FunctionArgs... args){
		f(args...);
	}
};

void func(int a){
	...
}

...
A<void(*)(int), int> a;
a.func(func, 45);

Jednakże coś takiego nie gwarantuje, że FunctionArgs... będzie odpowiednie dla FunctionType. Jest to również niewygodne, bo trzeba pisać jakby dwa razy to samo.
Z góry dziękuje za pomoc.

2

Można zrobić to po prostu tak

template<typename FunctionType>
class A
{
public:
    template <typename... FunctionArgs>
    void func(FunctionType f, FunctionArgs... args)
    {
        f(args...);
    }
};

void func(int a)
{
    std::cout << a << '\n';
}

int main()
{
    A<void(*)(int)> a;
    a.func(func, 33);
    a.func(func, 3.4);
    a.func(func, 3.4f);
    a.func(func, false);
    //a.func(func, "error");
    return 0;
} 

Ale trochę bez sensu ten kod jest.
Bo równie dobrze można napisać

func(45)
0
Sopelek napisał(a):

Ale trochę bez sensu ten kod jest.
Bo równie dobrze można napisać

func(45)

Tak, bo to tylko przykład obrazujący mój program.

Dzięki, chyba o to mi chodziło. Chyba, bo coś takiego nie pozwoli mi na to, abym mógł użyć typu listy argumentów(czy jak to tam się zwie) w obrębie całej klasy(nie wiem jeszcze czy tego potrzebuję).

0

Niestety rozwiązanie, które zaprezentował @Sopelek nie uwzględnia problemu perfect forwarding. Przykładowe rozwiązanie Twojego problemu i perfect forwardingu zarazem:

 
template<typename ...Args>
struct Package {
  Package(Args&&... tmp_args) : args(std::forward<Args>(tmp_args)...) {}
  std::tuple<Args...> args;
};

template<typename FunctionReturnType, typename ...FunctionArgs>
class A {
public:
  typedef std::function< FunctionReturnType( FunctionArgs&&... ) > Function;
  void func(Function f, FunctionArgs&&... args) {
    m_package.reset(new Package<FunctionArgs...>(std::forward<FunctionArgs>(args)...));
    f(std::forward<FunctionArgs>(args)...);
  }

private:
  std::unique_ptr<Package<FunctionArgs...>> m_package;
};

void foo(int value) {
  std::cout << "int foo(int)" << std::endl; // g++ std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int bar(int& a, float b, std::string& str) {
  std::cout << "int bar(int&, float, std::string&)" << std::endl;
  return 1;
}

int main() {
  A<void, int> a;
  a.func(foo, 5);
  A<int, int&, float, std::string&> aa;
  int int_a = 1;
  std::string string_c = "Ala ma kota";
  aa.func(bar, int_a, .5f, string_c);
  return 0;
}

Output:
  int foo(int)
  int bar(int&, float, std::string&)

1 użytkowników online, w tym zalogowanych: 0, gości: 1