【发布时间】:2020-09-03 14:30:29
【问题描述】:
我认为这个问题可能更多地是关于我对模板做任何不平凡的事情的弱点,而不是问题本身,但我想实现一个这样使用的模板类:
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 */
}
}
};
(当然,在现实生活中,我更可能使用枚举值而不是原始整数,但这用最少的示例代码就可以理解。)
标准:
- 如果索引在编译时未知,则需要工作
- 访问应该使用 switch 语句或等效的语句,而不是通过允许的键进行运行时线性搜索。
- 不想要一个像
std::unordered_map这样的有潜在桶冲突的hashmap
我也很高兴有一个解释如何编写这种模板代码的参考。
【问题讨论】:
-
关于您的第一点:您是指来自
MyArray<std::string, 1, 3, 7>的可用索引还是来自例如请求的索引a[1] = "hello";? -
@Quentin:我的意思是像
int i; std::cin >> i; std::cout << a[i]这样的东西应该可以编译。 -
实现 switch case 很简单,但这是一个线性搜索。您在寻找完美的哈希吗?
-
没有线性要求...您可以使用
std::map,通过构造函数创建所需的值,并在运行时抛出异常,通过对应于非当前值的索引访问地图.问题是std::map是(如果我没记错的话)O(n log(n)) -
@AtnNn:我希望是这样,但看起来至少 g++ 会很高兴地为等效的 if/elseif/else 块生成一个巨大的线性搜索:godbolt.org/z/ecTz19跨度>