gpt4 book ai didi

c++ - 实例化一个模板类,该模板类在具有不同函数签名的构造函数中采用函数指针

转载 作者:行者123 更新时间:2023-11-30 01:40:05 26 4
gpt4 key购买 nike

我有一个模板类,它在构造函数中接受一个函数指针。类中的方法稍后将根据条件调用该函数。我可以拥有该类的 2 个对象,每个对象都使用具有不同签名的函数指针实例化吗?简化代码如下。

#include <iostream>
using namespace std;

template <class FUNC>
class Thread {
public:
Thread(FUNC f1, int i)
: f(f1), val(i) {};

void run() {
if (val == 1)
f();
else
f(val); // here
}
private:
FUNC f;
int val;
};

void print() {
cout << "print" << endl;
}

void incr(int a) {
cout << "incremented value is " << ++a << endl;
}

int main () {
Thread<void(*)()> t1(print,1);
t1.run();
Thread<void(*)(int)> t2(incr,2);
t2.run();
}

run() 根据val 决定调用哪个函数。两个概率函数都有不同的签名。执行此操作时出现以下编译错误。

    testa.cpp: In member function 'void Thread<FUNC>::run() [with FUNC = void (*)()]':
testa.cpp:33: instantiated from here
testa.cpp:16: error: too many arguments to function
testa.cpp: In member function 'void Thread<FUNC>::run() [with FUNC = void (*)(int)]':
testa.cpp:35: instantiated from here
testa.cpp:14: error: too few arguments to function

我该怎么做?在 C++ 中有没有一种方法首先使用模板来做到这一点?

最佳答案

我认为您的 Thread 类强制客户端提供一个 int 参数,无论函数指针是否在所有点都接受参数设计缺陷。您希望客户端仅传递他们需要的参数。

使用模板实现此目的的一种方法是使用模板特化来捕获哪些参数是必需的,如下所示:

template<class...>
class Thread;

template <class RET, class... ARGS>
class Thread<RET(*)(ARGS...)> {/*..*/}

从那里开始,特化的其余部分几乎是自写的。如果您可以处理开销,我建议使用 std::functionlambda 实例化这样您就可以绑定(bind)在 Thread 的构造函数中接收到的参数。这很好,因为它使 Thread 中的持有类型保持一致。这样您就不必尝试在 f()

的两个版本之间进行某种运行时切换
template <class RET, class... ARGS>
class Thread<RET(*)(ARGS...)> {
public:
using fptr_t = RET(*)(ARGS...);

Thread(fptr_t fptr, ARGS... args)
{
f = [fptr, args...]{fptr(args...);};
}

void run() {
f();
}
private:
std::function<void(void)> f;
};

Demo

当然,对于生产环境,这段代码应该变得更加复杂,考虑复制/移动两个 Thread 对象,而且还要移动参数的语义以绑定(bind)到函数指针。

关于c++ - 实例化一个模板类,该模板类在具有不同函数签名的构造函数中采用函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44200220/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com