c++ - 如何在初始化时使用可变参数来在初始化时包括不同数量的对象?

标签 c++ templates initialization compile-time

这是上一个问题(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/

相关文章:

c++ - lstd++ 和 extern - 从 C 调用 C++

c++ - boost signals2 重复的变量名

c++ - 错误 : this declaration has no storage or type specifier

c++ - 不可移植的代码在模板实例化中产生 "no operator matches these operands"错误

php - 是否有必要在 PHP 中初始化/声明变量?

c++ - leveldb 示例不适用于 Windows : Error LNK2029

c++ - 在 C++ 中使用双字检查多个 bool 条件

C++ 模板编程 : how to call type's function?

swift - 在 Swift 中,创建对象时在便利初始值设定项中出现语法错误

C中比较两个char数组的内容