如何解决如何在初始化时使用可变参数来在初始化时包括不同数量的对象?
这是上一个问题(Link)的扩展
我需要根据提供的“定义”和不同的ctor参数包括不同数量的对象。第一个参数是对象从零到(NUMBER-1)的“索引”,其他参数是可选的。
到目前为止,当仅显示单个“索引”参数时,我还没有问题,但是我仍在努力添加可选参数Args... args
。
这就是我要尝试的方法。假设我们要实例化以下两个类
class Output
{
public:
explicit Output(uint32_t idx) : m_idx(idx) { printf("ctor: %u\n",m_idx); };
private:
uint32_t m_idx = -1;
};
class Input
{
public:
explicit Input(uint32_t idx,std::string name) : m_idx(idx),m_name(name) { printf("ctor: %u [%s]\n",m_idx,m_name.data()); };
private:
uint32_t m_idx = -1;
std::string m_name;
};
有2个可通过顺序索引实例化的模板
template<typename T,typename... Args,typename TInts,TInts... I>
constexpr auto MakeArrayHelper(Args... args,std::integer_sequence<TInts,I...>)
{
return std::array<T,sizeof...(I)>{ (I)...,std::forward<Args>(args)... };
}
template <typename T,size_t Count,typename BaseType = uint32_t>
constexpr auto MakeArray(Args... args)
{
return MakeArrayHelper<T>((args)...,std::make_integer_sequence<BaseType,Count>());
}
我想实例化这样的类
auto outputs = MakeArray<Output,5>();
auto inputs = MakeArray<Input,3>(std::string("Analog"));
expanded into:
std::array<Output,5> = { Output{0},Output{1},Output{2},Output{3},Output{4} };
std::array<Input,3> = { Input{0,"Analog"},Input{1,Input{2,"Analog"} };
这给我带来了一个编译错误:could not deduce template argument for 'TInts'
您能帮助我了解我做错了什么吗? 谢谢。
解决方法
如果没有完整的示例,很难给出完整的答案,但是...我在MakeArrayHelper()
中看到了一些问题
首先,参数的可变参数包必须位于最后一个位置,否则推导将失败。
所以,而不是
template<typename T,typename... Args,typename TInts,TInts... I>
constexpr auto MakeArrayHelper(Args... args,std::integer_sequence<TInts,I...>)
您可以尝试
template<typename T,TInts... I,typename... Args>
constexpr auto MakeArrayHelper(std::integer_sequence<TInts,I...>,Args ... args)
第二:如果要使用转发,则args
参数必须是转发引用
template<typename T,Args && ... args)
// .....................................................................^^
第三:在函数内部,您声明了std::array<T,sizeof...(TInts)>
,但您使用了它来初始化
{ (I)...,std::forward<Args>(args)... };
一系列sizeof...(TInts)
和一些args...
。
我不明白您想要获得什么,但这显然是错误的。
-编辑--
或者也许我理解您想要什么...如果我理解正确,那么您想要的就是(警告:未经测试的代码)
template <typename T,typename ... Args>
constexpr auto MakeArrayHelper (std::integer_sequence<TInts,Args const & ... args)
{
return std::array<T,sizeof...(I)>{ T{I,args...} ... };
}
template <typename T,std::size_t Count,typename BaseType = std::uint32_t,typename ... args>
constexpr auto MakeArray (Args const & ... args)
{
return MakeArrayHelper<T>(std::make_integer_sequence<BaseType,Count>(),args...);
}
避免在args...
中转发MakeArrayHelper()
,因为您不能(毫无风险)多次转发同一变量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。