我认为这个问题可能更多是关于我对模板所做的任何琐碎事情而不是问题本身的弱点,但我想实现这样使用的模板类:
MyArray<std::string, 1, 3, 7> a;
a[1] = "hello";
a[3] = "world";
a[7] = "!";
// runtime error
// a[4] = "?";
在幕后,MyArray<std::string, 1, 3, 7>
基本上等同于以下内容:class C
{
private:
std::string _values[3];
public:
std::string & operator[](std::size_t index)
{
switch(index)
{
case 1: return _values[0];
case 3: return _values[1];
case 7: return _values[2];
default: /* some error condition */
}
}
};
(当然,在现实生活中,与原始整数相比,我更可能使用枚举值,但这可以使示例代码最少。)条件:
std::unordered_map
我也很乐意提供引用,该引用说明了如何编写这种模板代码。
最佳答案
好的,如果您不介意可能的巨大空间成本,则可以这样做:
template<typename T, size_t Head, size_t... Tails>
class MagicArray{
std::array<T, 1 + sizeof...(Tails)> data;
static constexpr size_t max(size_t a, size_t b) noexcept{
return (a < b) ? b : a;
}
template<typename head, typename... tails>
static constexpr size_t max(head a, tails... b) noexcept{
if constexpr (sizeof...(b) == 0)
return a;
else
return max(a, max(b...));
}
static constexpr size_t value_max = max(Head, Tails...);
template<size_t addition, size_t I, size_t A, size_t... B>
static constexpr size_t find() noexcept{
if constexpr (I == A)
return addition;
else if constexpr (sizeof...(B) == 0)
return value_max;
else
return find<addition + 1, I, B...>();
}
template<size_t... Is>
static constexpr std::array<size_t, value_max + 1> generation(std::index_sequence<Is...>*) noexcept{
return { (find<0, Is, Head, Tails...>())... };
}
static constexpr std::array<size_t, value_max + 1> mapping = generation((std::make_index_sequence<value_max + 1>*)nullptr);
public:
T& operator[](size_t index){
if (index > value_max || mapping[index] == value_max)
throw 0;
else
return data[mapping[index]];
}
T const& operator[](size_t index) const{
if (index > value_max || mapping[index] == value_max)
throw 0;
else
return data[mapping[index]];
}
};
int main(){
MagicArray<std::string, 1, 3, 7> a;
a[1] = "Hello";
a[3] = "World";
a[7] = "!";
a[9] = "Boooooooooooooooom!";
}
关于c++ - C++编译时关联数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63725780/