C++ function pointer as Template parameter

时间:2021-04-29 21:40:33

I have questions with below code snippet, not sure if I correctly understand the codes.

我对下面的代码片段有疑问,不确定我是否正确理解代码。

template <typename R, typename... Args>                                     
class RunnableAdapter<R(*)(Args...)> {
 public:
  typedef R (RunType)(Args...);

  explicit RunnableAdapter(R(*function)(Args...))   
      : function_(function) {
  }

  R Run(Arg... args) {
    return function_(args...);
  }

 private:
  R (*function_)(Args...);
};
  1. <R(*)(Args...)> is a "type of function pointer"and blink space between R and (*) is not necessarily required?

    是“函数指针的类型”,R和(*)之间的闪烁空间不一定是必需的吗? (*)(args>

  2. and what could instanciation of RunnableAdapter be? I assume it is like below.
    void myFunction(int i){ // }; RunnableAdfapter<(void)(*)(int)> ra(MyFunction); ra.Run(1); //which calls MyFunction(1)

    什么可以实现RunnableAdapter的实例化?我假设它就像下面。 void myFunction(int i){//}; RunnableAdfapter <(void)(*)(int)> ra(MyFunction); ra.Run(1); //调用MyFunction(1)

1 个解决方案

#1


1  

At first the code you provided have some mistakes and does not even compile. To answer tou questions:

首先,您提供的代码有一些错误,甚至不编译。回答tou问题:

  1. Spaces are not necessary.
  2. 空间不是必需的。
  3. See below example
  4. 见下面的例子

You could declare you class like this

你可以像这样申报你的课程

template <typename T>
class RunnableAdapter;

template <typename R, typename... Args>                                     
class RunnableAdapter<R(*)(Args...)> { ... }

And instantiate it

并实例化它

RunnableAdapter<void(*)(int)> ra(&myFunction);

But you could simplify it (here is full working example)

但你可以简化它(这是完整的工作示例)

#include <iostream>
#include <string>

template <typename T>
class RunnableAdapter;

template <typename R, typename... Args>                                     
class RunnableAdapter<R (Args...)> {
public:

  explicit RunnableAdapter(R(*function)(Args...))   
      : function_(function) {
  }

  R Run(Args... args) {
    return function_(args...);
  }

private:
  R (*function_)(Args...);
};

void myFunction(int i){ std::cout << i << std::endl; }

int main()
{
    RunnableAdapter<void(int)> ra(&myFunction);
    ra.Run(1);
}

This would allow instantiation with signature-like expressions like void(int). It just looks better, no need in (*).

这将允许使用像void(int)这样的类似签名的表达式进行实例化。它看起来更好,不需要(*)。

Also here is another way is to do it without class specialization, like this. The result is the same, but class declaration and instantiation is slightly different.

另外,另一种方法是在没有类专业化的情况下这样做。结果是一样的,但类声明和实例化略有不同。

#include <iostream>
#include <string>

template <typename R, typename... Args>                                     
class RunnableAdapter {
public:

  explicit RunnableAdapter(R(*function)(Args...))   
      : function_(function) {
  }

  R Run(Args... args) {
    return function_(args...);
  }

private:
  R (*function_)(Args...);
};

void myFunction(int i){ std::cout << i << std::endl; }

int main()
{
    RunnableAdapter<void, int> ra(&myFunction);
    ra.Run(1);
}

EDIT

编辑

As @Jarod42 proposed it is better to make Run like this

正如@ Jarod42提出的那样,最好像这样制作Run

template<typename... Ts>
R Run(Ts&&... args) {
  return function_(std::forward<Ts...>(args)...);
}

#1


1  

At first the code you provided have some mistakes and does not even compile. To answer tou questions:

首先,您提供的代码有一些错误,甚至不编译。回答tou问题:

  1. Spaces are not necessary.
  2. 空间不是必需的。
  3. See below example
  4. 见下面的例子

You could declare you class like this

你可以像这样申报你的课程

template <typename T>
class RunnableAdapter;

template <typename R, typename... Args>                                     
class RunnableAdapter<R(*)(Args...)> { ... }

And instantiate it

并实例化它

RunnableAdapter<void(*)(int)> ra(&myFunction);

But you could simplify it (here is full working example)

但你可以简化它(这是完整的工作示例)

#include <iostream>
#include <string>

template <typename T>
class RunnableAdapter;

template <typename R, typename... Args>                                     
class RunnableAdapter<R (Args...)> {
public:

  explicit RunnableAdapter(R(*function)(Args...))   
      : function_(function) {
  }

  R Run(Args... args) {
    return function_(args...);
  }

private:
  R (*function_)(Args...);
};

void myFunction(int i){ std::cout << i << std::endl; }

int main()
{
    RunnableAdapter<void(int)> ra(&myFunction);
    ra.Run(1);
}

This would allow instantiation with signature-like expressions like void(int). It just looks better, no need in (*).

这将允许使用像void(int)这样的类似签名的表达式进行实例化。它看起来更好,不需要(*)。

Also here is another way is to do it without class specialization, like this. The result is the same, but class declaration and instantiation is slightly different.

另外,另一种方法是在没有类专业化的情况下这样做。结果是一样的,但类声明和实例化略有不同。

#include <iostream>
#include <string>

template <typename R, typename... Args>                                     
class RunnableAdapter {
public:

  explicit RunnableAdapter(R(*function)(Args...))   
      : function_(function) {
  }

  R Run(Args... args) {
    return function_(args...);
  }

private:
  R (*function_)(Args...);
};

void myFunction(int i){ std::cout << i << std::endl; }

int main()
{
    RunnableAdapter<void, int> ra(&myFunction);
    ra.Run(1);
}

EDIT

编辑

As @Jarod42 proposed it is better to make Run like this

正如@ Jarod42提出的那样,最好像这样制作Run

template<typename... Ts>
R Run(Ts&&... args) {
  return function_(std::forward<Ts...>(args)...);
}