gpt4 book ai didi

c++ - 包装函数指针和函数对象如何在通用代码中工作?

转载 作者:行者123 更新时间:2023-11-30 00:35:52 24 4
gpt4 key购买 nike

下面的模板定义

template <typename Func, typename ReturnType, typename... Arguments>
class Command
{
public:
Command(Func f) : m_func(f) { }
ReturnType operator()(Arguments... funcArgs) { return m_func(funcArgs...); }
private:
Func m_func;
};

在使用以下测试代码实例化时,使用 gcc 4.7.3 给出错误消息(错误:字段“Command::m_func”无效声明的函数类型):

void testFunction(int i, double d)
{
std::cout << "TestFunctor::operator()(" << i << ", " << d << ") called." << std::endl;
}

int main()
{
void (&fRef)(int, double) = TestFunction;
Command<void(int, double), void, int, double> testCommand(fRef);
}

如果我将不带寻址运算符的 TestFunction 传递给 testCommand 构造函数,也会出现错误消息,但如果我传递显式命名的函数指针或使用寻址运算符来传递参数,错误消息就会消失。我的印象是这段代码应该适用于现代 C++ 设计的第 5 章。

无法存储对函数的引用但函数指针工作正常的原因是什么?是否有任何解决方法可以在不失去对能够将仿函数作为参数传递给 Command 的构造函数的支持的情况下进行编译?

最佳答案

改变一行可以解决它:

Command<void(*)(int, double), void, int, double> testCommand(fRef);

区别在于,您现在传递的是函数指针,而不是函数类型。 (函数不可复制,但指针可以)。

当您传递它时,引用 fRef 衰减 为函数指针。

如果性能很重要,我不建议使用 std::function

查看 live on Coliru

请注意,只需稍加重写,您就可以使它工作得更好:

int main()
{
auto command = make_command(testFunction);
command(1, 3.14);
}

为此,我建议将 Command 模板更改为:

template <typename Func>
class Command
{
Func m_func;
public:
Command(Func f) : m_func(f) { }

template <typename... A> auto operator()(A... args) const
-> decltype(m_func(args...))
{ return m_func(args...); }
};

现在您可以通过工厂函数对 Func 模板参数进行类型推导:

template <typename Func> Command<Func> make_command(Func f)
{
return Command<Func>(f);
}

查看此方法 live on Coliru 也是。当然,输出是一样的:

TestFunctor::operator()(1, 3.14) called.

关于c++ - 包装函数指针和函数对象如何在通用代码中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17757128/

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