这是上一个问题(Link)的扩展
我需要根据提供的“定义”和不同的ctor参数包括不同数量的对象。第一个参数是对象从零到(NUMBER-1)的“索引”,其他参数是可选的。
到目前为止,当仅显示单个“index”参数时,我还没有问题,但是我仍在努力添加可选参数Args... args
。
这就是我要这样做的方式。假设我们要实例化以下两个类(class)
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... Args, 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, "Analog"}, 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, typename TInts, TInts... I, typename... Args>
constexpr auto MakeArrayHelper(std::integer_sequence<TInts, I...>, Args ... args)
第二:如果要使用转发,则args
参数必须是转发引用template<typename T, typename TInts, TInts... I, typename... Args>
constexpr auto MakeArrayHelper(std::integer_sequence<TInts, I...>, Args && ... args)
// .....................................................................^^
第三:在函数内部声明一个std::array<T, sizeof...(TInts)>
,但使用{ (I)..., std::forward<Args>(args)... };
一系列sizeof...(TInts)
和一些args...
。我不明白您想要获得什么,但这显然是错误的。
-编辑-
也许我了解您想要什么...如果我正确理解,您想要的是(警告:未经测试的代码)
template <typename T, typename TInts, TInts... I, typename ... Args>
constexpr auto MakeArrayHelper (std::integer_sequence<TInts, I...>, 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()
,因为您不能(毫无风险)多次转发同一变量。
关于c++ - 如何在初始化时使用可变参数来在初始化时包括不同数量的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63979128/