让我们定义输入:
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
类型的别名。
如何实现所需的功能?
答案 0 :(得分:3)
以下内容应该有效,但我使用std::array
取代了一些自由。它更方便一点。
每次调用value_getter<size,I>::get<T>
都需要std::array<T,2>
作为参数,并根据signs[I]
对其进行修剪,因此我们得到类型为T的arr[signs[I]
,这也是一个嵌套数组(如果我!= size)所以我们再次以T为参数调用value_getter<size,I>::get
。
一个帮助器value_getter
结构,用于逐个修剪嵌套数组。
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);
}
};
返回对值的引用的最终基本案例。
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数组样式一起使用,问题是如何在 std::array<T,2>
函数中表示类型::get
。它可以通过类似std::add_pointer<T>
的内容工作,该T*
应该从T
提供T
。
因此,对于C风格的数组来说,它实际上要简单得多。
这里arr
表示数组本身。如果我们绕过一些静态错误检查,T基本上不用作类型。由于我们知道T类型的I != size
是一个数组(如果operator[]
),那么我们始终可以在arr
上调用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;
}
};
基本情况再次微不足道。
io.on('connection', function (socket) {
socket.on('join', function(user) {
//list of connected users
connected_users.push({socket_id: socket.id, email: user.email});
socket.join(user.email);
});
...