如何在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_t
是 values
.
类型的别名
如何实现所需的功能?
以下应该有效,尽管我使用 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);
虽然我正在考虑如何使其与 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;
}
};
让我们定义输入:
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_t
是 values
.
如何实现所需的功能?
以下应该有效,尽管我使用 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);
虽然我正在考虑如何使其与 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;
}
};