C++ 11 - 数组的元组与元组的数组

3

给定一个 std::tuple,例如:

std::tuple<int, float, char>

我可以帮您翻译。需要生成这样的类型:
```

我想生成这样的类型:

```
std::tuple<std::vector<int>, std::vector<float>, std::vector<char>>

正如您所看到的,它是原始类型向量的元组。 这里是标准方案:

typedef std::tuple<int, float, char>    Struct;          // scenario 1
typedef std::vector<Struct>             ArrayOfStructs;  // scenario 2
typedef HereIsTheQuestion<Struct>::Type StructOfArrays;  // scenario 3

场景1旨在通过以下方式访问:

Struct x = ...; // single tuple
std::get<0>(x) = 11;
// etc.

场景2旨在这样访问:

ArrayOfStructs xs = ...; // array of tuples
for (size_t i=0; i<xs.size(); ++i) {
    std::get<0>(xs[i]) = 11;
    // etc.
}

场景3的访问方式如下所示:
StructsOfArrays xs = ...; // single tuple of arrays
size_t n = std::get<0>(xs).size(); // first tuple array size
for (size_t i=0; i<n; ++i) {
    std::get<0>(xs)[i] = 11;
    // etc.
}

如何编写 HereIsTheQuestion::Type 才能与原始结构类型的数组元组相似?

谢谢,m。

2个回答

4

以下是如何实现HereIsTheQuestion的方法。

template<typename T>       //primary template
struct HereIsTheQuestion;  //leave it undefined

template<typename ...T>
struct HereIsTheQuestion<std::tuple<T...>>  //partial specialization
{
    using Type = std::tuple<std::vector<T>...>;
};

现在
HereIsTheQuestion<std::tuple<int, float, char>>::Type

std::tuple<std::vector<int>,std::vector<float>, std::vector<char>>

希望这能帮到你。

@spattija: 是的,空元组将为 ::Type 返回空元组,也就是说 HereIsTheQuestion<std::tuple<>>::Type 将会是 std::tuple<> - undefined
对于我的无知,我写了BlahBlah<...>::Type,你觉得这是必要的吗?我的意思是,是否可以用HereIsTheQuestion<std::tuple<>>代替HereIsTheQuestion<...tuple...>::Type?(不使用内部typedef,即 --> ::Type)? - undefined
@spattija:我不明白你在说什么。请在ideone.com上编写你的代码,并给我链接。 - undefined
@spattija 使用类型别名,即 template <typename... T> using HereIsTheQuestion_t = typename HereIsTheQuestion<T...>::type; - undefined

3
您可以使用此模板创建以下类型:
namespace detail
{
    template <typename... Ts>
    struct tuple_change { };

    template <typename... Ts>
    struct tuple_change<std::tuple<Ts...>>
    {
        using type = std::tuple<std::vector<Ts>...>;
    };
}

并创建如下所示的索引序列:

namespace detail
{
    template <int... Is>
    struct index { };

    template <int N, int... Is>
    struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };

    template <int... Is>
    struct gen_seq<0, Is...> : index<Is...> { };
}

你还需要一个模板来允许元组的打印:

template <typename... Ts, int... Is>
static void print(std::tuple<Ts...>& var, detail::index<Is...>)
{
    auto l = { (print(std::get<Is>(var)), 0)... };
    (void)l;
}

template <typename... Ts>
static void print(std::tuple<Ts...>& var)
{
    print(var, detail::gen_seq<sizeof...(Ts)>{});
}

template <typename T>
static void print(std::vector<T>& v)
{
    for (auto a : v)
    {
        std::cout << std::boolalpha << a << std::endl;
    }
    std::cout << std::endl;
}

接下来就简单了。以下是您的程序:
#include <iostream>
#include <tuple>
#include <vector>

namespace detail
{
    template <typename... Ts>
    struct tuple_change { };

    template <typename... Ts>
    struct tuple_change<std::tuple<Ts...>>
    {
        using type = std::tuple<std::vector<Ts>...>;
    };

    template <int... Is>
    struct index { };

    template <int N, int... Is>
    struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };

    template <int... Is>
    struct gen_seq<0, Is...> : index<Is...> { };
}

template <typename... Args, int... Is>
void fill(std::tuple<Args...>& var, detail::index<Is...>)
{
    auto l = { (std::get<Is>(var).assign(5, 11), 0)... };
    // here I just decided to make the size 5
    (void)l;
}

template <typename... Args>
void fill(std::tuple<Args...>& var)
{
    fill(var, detail::gen_seq<sizeof...(Args)>{});
}

template <typename T>
static void print(std::vector<T>& v)
{
    for (auto a : v)
    {
        std::cout << std::boolalpha << a << std::endl;
    }
    std::cout << std::endl;
}

template <typename... Ts, int... Is>
static void print(std::tuple<Ts...>& var, detail::index<Is...>)
{
    auto l = { (print(std::get<Is>(var)), 0)... };
    (void)l;
}

template <typename... Ts>
static void print(std::tuple<Ts...>& var)
{
    print(var, detail::gen_seq<sizeof...(Ts)>{});
}

using result_type = detail::tuple_change<std::tuple<int, bool>>::type;

int main()
{
    result_type r;

    fill(r);
    print(r);
}

Demo


@spattija 你的意图是什么?你有三种不同的情况,我不确定你想要做什么。 - undefined
1
@spattija 您不想将其更改为向量的元组吗?这就是我在这里所做的。我还包含了一种以演示方式打印元组的方法。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接