C++11:std::get<> 等价于 n 维数组

标签 c++ c++11 templates template-meta-programming

我想知道是否有类似 std::get 的东西可以在编译时访问任何 n 维数组。例如。 get_value(arr, 1,2,3) 应返回值 arr[1][2][3]。我尝试使用递归模板 constexpr。但是,类型推导似乎有问题。

#include <iostream>
#include <string>
#include <array>

template <class T, class FIRST, class ... REST>
constexpr auto get_value(T arr, FIRST first, REST... rest) {
    auto sub = arr[first];
    using sub_t = decltype(sub);
    return get_value<sub_t, REST...>(sub, rest...);
}

// works for 1D
template<class T>
constexpr auto get_value(T arr, auto first) {
    return arr[first];
}

int main()
{
    using arr1_t = std::array<int, 5>;
    using arr2_t = std::array<arr1_t, 5>;

    arr1_t arr1 = {1,2,3,4,5};
    arr2_t arr2 = {arr1, arr1, arr1, arr1, arr1};

    std::cout <<  get_value(arr1, 1) << std::endl;
    std::cout <<  get_value(arr2, 1,1) << std::endl;
}

最佳答案

template <std::size_t I, std::size_t... Is, typename T>
auto get(const T& x)
{
    if constexpr(sizeof...(Is) == 0) { return x[I]; } 
    else { return get<Is...>(x[I]); }
}

用法:

using array4d = std::array<std::array<std::array<std::array<int, 6>, 6>, 6>, 6>;

int main()
{
    array4d a;
    a[1][2][3][4] = 42;
    assert((get<1, 2, 3, 4>(a)) == 42);
}

live wandbox example


如果你想要运行时版本:

template <typename T, typename... Is>
auto get(const T& x, std::size_t i, Is... is)
{
    if constexpr(sizeof...(Is) == 0) { return x[i]; } 
    else { return get(x[i], is...); }
}

用法:

int main()
{
    array4d a;
    a[1][2][3][4] = 42;
    assert(get(a, 1, 2, 3, 4) == 42);
}

live wandbox example


请注意,我使用 C++17 的 if constexpr 来定义递归的基本情况。在 C++11 中,您可以改为提供重载:

template <typename T>
int get(const T& x, std::size_t i)
{
    return x[i]; 
}


template <typename T, typename... Is>
int get(const T& x, std::size_t i, Is... is)
{
    return get(x[i], is...);
}

live example on wandbox

关于C++11:std::get<> 等价于 n 维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46034625/

相关文章:

c++ - C++03 中的 Lambda

c++ - printf或iostream如何指定点后的最大位数

c++ - 嵌套的 std::initializer_lists 的数据元素是否保证是连续的?

c++ 'Undefined Reference' 具有多种数据类型的模板类

c++ - 将shared_ptr的 vector 复制到抽象基的派生类

c++ - 尝试连接到 tcp 套接字时连接被拒绝 (linux)

c++ - getline() 省略了数组输出的第一个字母。

jquery - Grails动态更新模板 View 而无需Ajax

c++ - 编译时模板 `std::integral_constant` 计数器 - 如何实现它?

c++ - 我该如何解决libstdc++可移植性问题