如何在C++11中将整数序列扩展为下标运算符?

How to expand integer sequence into subscript operator in C++11?

让我们定义输入:

double values[2][2]...[2] N times
bool signs[N];

我想做的是为这样的东西写一个模板函数:

auto result = values[signs[0]][signs[1]]...[signs[N - 1]];

不幸的是,没有 C++17 的折叠表达式我无法实现它。

我确定我需要以某种方式使用 std::index_sequence<>:

template <std::size_t ... indices>
double get_value(const dimension_creator_t<sizeof...(indices)>& values, 
                 index_sequence<indices...>, bool (&signs)[sizeof...(indices)])

但不确定如何进行。我可以在网上找到 std::integer_sequence 的代码。 dimension_creator_tvalues.

类型的别名

如何实现所需的功能?

以下应该有效,尽管我使用 std::array 代替了一些自由。只是方便了一点。

value_getter<size,I>::get<T>的每次调用都将std::array<T,2>作为参数,trim它基于signs[I],所以我们得到类型T的arr[signs[I],它是又是一个嵌套数组(如果 I != size)所以我们再次调用 value_getter<size,I>::get 并以 T 作为参数。

一个助手 value_getter 结构,用于逐个获取 trim 嵌套数组。

template <std::size_t size, std::size_t I> struct value_getter {
template <typename T>
    static double& get(std::array<T,2>& arr, const std::array<bool, size>& signs) {
        return value_getter<size, I+1>::template get(arr[signs[I]], signs);
    }
};

returns 对值的引用的最终基本情况。

template <std::size_t size> struct value_getter<size, size> {
    static template <typename T> double& get(T& arr, const std::array<bool, size>& signs) {
        return arr;
    }
};

用法:

 std::array< std::array< std::array< double, 2>, 2>, 2> values{};
 std::array<bool, 3> signs{};

 double v = value_getter<3,0>::template get(values, signs);

Demo

虽然我正在考虑如何使其与 C 数组样式一起使用,但问题是如何在 ::get 函数中表示类型 std::array<T,2>。它可以通过像 std::add_pointer<T> 这样的东西来工作,它应该从 T.

给出 T*

所以对于 C 风格数组来说实际上要简单得多。

此处T表示数组本身。如果我们绕过一些静态错误检查,T 基本上就不会被用作类型。因为我们知道类型 T 的 arr 是一个数组(如果 I != size)那么我们总是可以在 arr.

上调用 operator[]
template <std::size_t size, std::size_t I> struct value_getter {
template <typename T>
    static double& get(T arr, bool *signs) {
        return value_getter<size, I+1>::template get(arr[signs[I]], signs);
    }
};

基本情况再次变得微不足道。

template <std::size_t size> struct value_getter<size, size> {
    static double& get(double& arr, bool * signs) {
        return arr;
    }
};

Demo(C array)