【发布时间】:2019-10-23 22:49:02
【问题描述】:
有没有办法生成编译时 switch 语句以匹配索引?例如,如果我有一个序列1,5,8 并且我想将它与0,1,2 匹配,编译器有没有办法在编译时生成一个函数,当给定 1、5、8 时分别返回 0、1、2 .为了更好地说明我想要什么,我准备了这个稀疏数组结构:https://godbolt.org/z/QpWVST
#include <tuple>
#include <limits>
template<size_t depth, size_t Idx, size_t I, size_t...Is>
size_t get_idx()
{
static_assert(Idx==I || sizeof...(Is)>0, "Index not found.");
if constexpr(Idx==I) return depth;
else return get_idx<depth+1, Idx,Is...>();
}
template<typename T, size_t... Is>
struct sparse_array
{
constexpr static size_t N = sizeof...(Is);
constexpr static size_t size() { return N; }
T e[N];
constexpr sparse_array() : e{} {}
template<typename...type_pack>
constexpr sparse_array(const type_pack&... pack) : e{ pack... }
{
static_assert(sizeof...(type_pack) == size(), "Argument count must mach array size.");
}
template<size_t I>
constexpr size_t idx()
{
return get_idx<0, I, Is...>();
}
size_t idx(const size_t i)
{
// how to achieve somethig like this?
return idx<i>();
}
constexpr T& at(size_t idx)
{
return e[idx];
}
};
template<typename T, size_t...Is>
auto make_dense_array(std::index_sequence<Is...>&& seq)
{
return sparse_array<T, Is...>{};
}
template<typename T, size_t N>
using dense_array = decltype(make_dense_array<T>(std::declval<std::make_index_sequence<N>>()));
size_t test()
{
dense_array<int, 3> a;
sparse_array<int,1,5,8> b;
return b.idx<8>();
}
我还希望能够传入运行时变量,这些变量将通过带有索引的开关并返回相应的相应索引。我解决这个问题的唯一想法是生成一个Is... 序列的数组,然后使用 if 语句进行 for 循环以返回正确的索引。另一种选择是使用地图(但这也不是编译时)。 sparse_array 通常会非常小,我希望能够在编译时间内完成大多数事情。
【问题讨论】:
标签: c++ templates c++17 sparse-matrix index-sequence