gpt4 book ai didi

c++ - 可以在函数签名中使用的可变类型定义

转载 作者:搜寻专家 更新时间:2023-10-31 01:43:38 25 4
gpt4 key购买 nike

基本上,我只想将任何可调用对象及其参数包装在一个稍后可以调用的任务对象中。下面是我想到的代码:

假设所有那些可调用类型都有一个成员类型,它们看起来好像是这样定义的:

template<typename TReturn, typename...TArgs>
struct SomeFunction{
using ArgTypes = TArgs; // won't compile of course
}

任务模板可以这样定义:

template<typename TFunction>
class Task {
public:
Task(TFunction fun, typename TFunction::ArgTypes...args) // won't compile
: fun_(fun), args_(args){}
void operator()()
{
fun_(args_...); // won't compile: workaround 1
}
private:
typename TFunction::ArgTypes... args_; // won't compile: workaround 2
TFunction fun_;
};

问题出在任务构造函数的定义上。有什么办法可以实现吗?当然我可以将其定义为模板构造函数:

template<typename...TArgs>
Task(TFunction fun, TArgs...args)

但是这样编译器就不知道 TArgs 和 TFunction::ArgTypes 是一样的。因此,当错误的参数传递给它时,错误消息是荒谬的。

解决方法 1:C++ How to store a parameter pack as a variable

解决方法 2:Is it possible to "store" a template parameter pack without expanding it?

最佳答案

你可以使用 std::tuple<TArgs...>存储参数并将它们解压缩到调用操作符中。如果你想定义 TArgs以某种方式在函数类型中,您应该将它们定义为一个元组:

template<typename TReturn, typename...TArgs>
struct SomeFunction{
using ArgTypesTuple = std::tuple<TArgs...>;
// ^^^^^^^^^^
}

但尽管如此,我认为不值得将参数保存在您的 Task 中。具有大量样板代码的对象...调用运算符将​​参数从元组重构/解压缩到参数列表时看起来有些难看。

更简单的解决方案是创建一个 lambda,它在构建 Task 时捕获参数对象,它甚至不再需要是模板:

class Task {
public:
template<typename TFunction, typename ...ArgTypes>
Task(TFunction fun, ArgTypes... args)
: fun_([=]{ fun(args...); }) {}
void operator()()
{
fun_();
}
private:
std::function<void()> fun_;
};

关于c++ - 可以在函数签名中使用的可变类型定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24802126/

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