C++ 如何在编译时在初始值设定项列表中包含具有可变参数的不同数量的对象?

C++ 如何在编译时在初始值设定项列表中包含具有可变参数的不同数量的对象?,c++,templates,initialization,compile-time,C++,Templates,Initialization,Compile Time,这是前一个问题()的延伸 我需要根据提供的“定义”和不同的参数包括不同数量的对象。第一个参数是对象从零到(数字1)的“索引”,其他参数是可选的 到目前为止,当只显示一个“index”参数时,我没有遇到任何问题,但我仍然在添加可选参数Args。。。args 这就是我试图做到的。假设我们要实例化下面的2个类 class Output { public: explicit Output(uint32_t idx) : m_idx(idx) { printf("ctor: %u\n&q

这是前一个问题()的延伸

我需要根据提供的“定义”和不同的参数包括不同数量的对象。第一个参数是对象从零到(数字1)的“索引”,其他参数是可选的

到目前为止,当只显示一个“index”参数时,我没有遇到任何问题,但我仍然在添加可选参数
Args。。。args

这就是我试图做到的。假设我们要实例化下面的2个类

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;
};
有两个模板需要使用顺序索引进行实例化

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>());
}
模板
constexpr自动生成数组帮助器(Args…Args,std::integer\u序列)
{
返回std::array{(I)…,std::forward(args)…};
}
模板
constexpr自动生成数组(Args…Args)
{
返回MakeArrayHelper((args)…,std::make_integer_sequence());
}
我想实例化这样的类

    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"} };
auto outputs=MakeArray();
自动输入=MakeArray(标准::字符串(“模拟”);
扩展为:
数组={Output{0},Output{1},Output{2},Output{3},Output{4};
数组={Input{0,“模拟”},Input{1,“模拟”},Input{2,“模拟”};
这给我留下了一个编译错误:
无法推断'TInts'的模板参数。

你能帮我理解我做错了什么吗。
谢谢。

没有完整的例子很难给出完整的答案,但是。。。我在
MakeArrayHelper()中看到一些问题

首先,可变参数包必须位于最后位置,否则演绎失败

因此,与其

template<typename T, typename... Args, typename TInts, TInts... I>
constexpr auto MakeArrayHelper(Args... args, std::integer_sequence<TInts, I...>)
第三:在函数内部声明一个
std::array
,但用

{ (I)..., std::forward<Args>(args)... };

避免在
MakeArrayHelper()
中转发
args…
,因为您不能(没有风险)多次转发同一变量。

如果没有完整的示例,很难给出完整的答案,但是。。。我在
MakeArrayHelper()中看到一些问题

首先,可变参数包必须位于最后位置,否则演绎失败

因此,与其

template<typename T, typename... Args, typename TInts, TInts... I>
constexpr auto MakeArrayHelper(Args... args, std::integer_sequence<TInts, I...>)
第三:在函数内部声明一个
std::array
,但用

{ (I)..., std::forward<Args>(args)... };

避免在
MakeArrayHelper()
中转发
args…
,因为您不能(没有风险)多次转发同一变量。

请发布一篇文章。任何人都不应该用片段组装出一个可复制的示例,并填写缺少的
#include
指令。我看到有人试图找到解决方案,但我不清楚它试图解决什么问题。你能描述一下这些助手应该扩展到什么方面吗?请发布一篇文章。任何人都不应该用片段组装出一个可复制的示例,并填写缺少的
#include
指令。我看到有人试图找到解决方案,但我不清楚它试图解决什么问题。你能描述一下帮助程序应该扩展到什么吗?我想,
T{I,args…}…
是op想要的,因为使用的类都有一个索引成员。@IlCapitano-我想你是对的:
I
不仅仅是生成序列,还是构造函数的参数。这也使得代码更简单。更正。谢谢,这就是我要做的@max66感谢您的详细解释。我认为,
T{I,args…}…
是op想要的,因为使用的类都有一个索引成员。@IlCapitano-我想您是对的:
I
不仅是生成序列,还是构造函数的参数。这也使得代码更简单。更正。谢谢,这就是我要做的@max66感谢您的详细解释。
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...);
 }