将initializer_list <t>转换为initializer_list <vector <t>&gt;在编译时</vector <t> </t>

时间:2014-08-23 18:43:38

标签: c++ initializer-list constexpr

我有一个接受

的类构造函数
initializer_list<T>

此构造函数必须运行接受

的父类构造函数
initializer_list<vector<T>>.

所以我必须将初始化列表转换为2d初始化列表。

{1, 2, 3, 4} to { {1}, {2}, {3}, {4} }

编辑:

我有一个接受

的类构造函数
initializer_list<T>

此构造函数必须运行接受

的父类构造函数
initializer_list<array<T, 1>>.

所以我必须将初始化列表转换为2d初始化列表。

{1, 2, 3, 4} to { {1}, {2}, {3}, {4} }

3 个答案:

答案 0 :(得分:3)

为什么不让你的子类使用参数包并将其转发给父构造函数?

struct Parent
{
    template<typename T>
    Parent(std::initializer_list<std::array<T, 1>>) { }

    virtual ~Parent() = default;
};

struct Child : Parent
{
    template<class... Args>
    Child(Args&&... args) : Parent{{{args}...}} { }
};

答案 1 :(得分:2)

std::initializer_list<T>是一个奇怪的混合体:创建一个,你需要静态地知道它的大小和内容,但是一旦你得到一个,你就无法静态地确定它的内容!换句话说,我认为您不能从std::initializer_list<std::vector<T>>创建std::initializer_list<T>

可以做的是采用可变参数列表,可能是约束使所有相同类型和类型成为整数,并从中构造std::initializer_list<std::vector<T>>

template <typename T>
void g(std::initializer_list<T> list) { ... }

template <typename... T>
void f(T... args) {
    g({ std::array<T, 1>(args)... });
}

答案 2 :(得分:2)

下面你可以找到一个完整的例子,如果你仍然在构造函数中混合<typename T>来自类'声明和<typename... Args>包的麻烦:

#include <iostream>
#include <array>
#include <utility>
#include <initializer_list>

template <typename T>
class A
{
public:
    A(std::initializer_list<std::array<T, 1>> i);

    virtual ~A() = default;
};

template <typename T>
A<T>::A(std::initializer_list<std::array<T, 1>> i)
{
    std::cout << i.size() << std::endl;
}

template <typename T>
class B : public A<T>
{
public:
    template <typename... Args>
    B(Args&&... args);
};

template <typename T>
template <typename... Args>
B<T>::B(Args&&... args) : A<T>{std::array<T, 1>{std::forward<Args>(args)}...}
{

}

int main()
{
    B<int> b{ 1, 2, 3, 4, 5, 6, 7 };
    return 0;
}

Live demo link.