我目前正在尝试实现通用的初始化程序,以减少代码库的大小。但是,在某一时刻,我的代码看起来像这样:
template<typename T, typename Arg1, typename Arg2>
T* ManageDevice(Arg1 arg1, Arg2 arg2)
{
auto device = new T{ arg1, arg2 };
// More operations on device
return device;
}
template<typename T, typename Arg1, typename Arg2, typename Arg3>
T* ManageDevice(Arg1 arg1, Arg2 arg2, Arg3 arg3)
{
auto device = new T{ arg1, arg2, arg3 };
// More operations on device
return device;
}
template<typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
T* ManageDevice(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
{
auto device = new T{ arg1, arg2, arg3, arg4 };
// More operations on device
return device;
}
哪个开始不太优雅。据我了解,可变参数模板似乎是解决此问题的方法。但是我不知道如何将其应用于我的情况。
我希望这样:
T* ManageDevice(Args... args)
{
// The function I want
// Unpack as a std::initializer_list
auto allArguments = unpackAll();
auto device = new T{ allArguments };
// More operations on device
return device;
}
关于应如何实现unpackAll()的任何建议? 谢谢。
答案 0 :(得分:3)
auto device = new T{ allArguments };
只是需要
auto device = new T{ args... };
在T{ args... }
中,args...
会为您扩展参数包到arg0, arg1, ..., argn
。
您可以看到它与之配合使用
template <typename... Args>
std::vector<int> make_vector(Args... args)
{
return {args...};
}
int main()
{
auto foo = make_vector(1,2,3,4);
for (auto e : foo)
std::cout << e << " ";
}
编辑以添加完善的转发版本
template <typename... Args>
std::vector<int> make_vector(Args&&... args)
{
return {std::forward<Args>(args)...};
}
答案 1 :(得分:0)
我的C ++ 14答案,作为最小的工作示例
$(".child").next().next()...
您需要根据需要对代码结构进行一些编辑。但是请注意,#include <initializer_list>
#include <utility>
#include <vector>
#include <type_traits>
#include <iostream>
struct example {
template <typename ...Args, typename T = std::common_type_t<Args...>>
static std::vector<T> foo(Args&& ...args) {
std::initializer_list<T> li{std::forward<Args>(args)...};
std::vector<T> res{li};
return res;
}
};
int main() {
std::vector<int> v1 = example::foo(1,2,3,4);
for(const auto& elem: v1)
std::cout << elem << " ";
std::cout << "\n";
}
构造函数采用vector
,并且该列表是通过该静态initializer_list
方法的参数包生成的。
编辑:就您的情况而言,就像其他人指出的那样,您可以直接将参数包转发给您的呼叫。我的回答显示将它们传递到foo
。
实际上,您可以这样做
initializer_list
,这些参数将隐式转换为static std::vector<T> foo(Args&& ...args) {
std::vector<T> res{std::forward<Args>(args)...};
return res;
}
。我明确显示了参数包中initializer_list
的构造。