[英]Why doesn't `std::initializer_list` provide a subscript operator?
Suppose that you are writing a function that accepts an std::initializer_list
called list
, and that the function requires random access to list
's elements. 假设您正在编写一个接受名为
list
的std::initializer_list
的函数,并且该函数需要对list
的元素的随机访问。 It would be convenient to write list[i]
instead of list.begin()[i]
. 写
list[i]
而不是list.begin()[i]
会很方便。 So why doesn't std::initializer_list
provide a definition of operator[]
? 那么,为什么
std::initializer_list
提供operator[]
的定义?
I can't think of any cases where an operator[]
returning const T&
would not be well-defined. 我无法想到在任何情况下,
operator[]
返回const T&
的定义都不明确。 Efficiency doesn't seem to be the issue here, since std::initializer_list<T>::iterator
is aliased to const T*
, which is clearly a random-access iterator. 效率似乎不是问题所在,因为
std::initializer_list<T>::iterator
被别名为const T*
,这显然是一个随机访问迭代器。
According to Bjarne Stroustrup in Section 17.3.4.2 (p. 497) of The C++ Programming Language, 4th Edition: 根据Bjarne Stroustrup在C ++编程语言,第4版的17.3.4.2(p。497)中的描述:
Unfortunately, initializer_list doesn't provide subscripting.
不幸的是,initializer_list不提供下标。
No further reason is given. 没有进一步的原因。
My guess is that it's one of these reasons: 我的猜测是这是以下原因之一:
2 and 4 sound kind of weak. 2和4声音有点微弱。 as does 3. My money's on 1.
就像3.我的钱在1。
It's indeed a bit annoying, not having square brackets operator for std::initializer_list, as the need for random direct access for a specific index is a reasonable scenario. 确实有点烦人,没有std :: initializer_list的方括号运算符,因为对于特定索引需要随机直接访问是一个合理的方案。
However, this ability can be added with some simple code: 但是,可以使用一些简单的代码来添加此功能:
// the class _init_list_with_square_brackets provides [] for initializer_list
template<class T>
struct _init_list_with_square_brackets {
const std::initializer_list<T>& list;
_init_list_with_square_brackets(const std::initializer_list<T>& _list): list(_list) {}
T operator[](unsigned int index) {
return *(list.begin() + index);
}
};
// a function, with the short name _ (underscore) for creating
// the _init_list_with_square_brackets out of a "regular" std::initializer_list
template<class T>
_init_list_with_square_brackets<T> _(const std::initializer_list<T>& list) {
return _init_list_with_square_brackets<T>(list);
}
Now we have a new global function named _ (underscore) which is probably not a good name for a global C++ method, unless we want to create some "undescore-like" utility lib for C++, which will have its own namespace, overloading the _ function for all sort of other useful usages. 现在,我们有了一个名为_(下划线)的新全局函数,它可能不是全局C ++方法的好名字,除非我们想为C ++创建一些“类似于unescore的”实用程序库,它将有自己的命名空间,从而使_函数可用于其他各种有用的用法。
The new _ function can be used now like this: 现在可以像下面这样使用新的_函数:
void f(std::initializer_list<int> list) {
cout << _(list)[2]; // subscript-like syntax for std::initializer_list!
}
int main() {
f({1,2,3}); // prints: 3
cout << _({1,2,3})[2]; // works also, prints: 3
return 0;
}
It is to be noted that the solution provided above is not a good bargain in terms of performance if you run over many items of std::initializer_list, as a temporary object of the suggested type above _init_list_with_square_brackets
is created repeatedly. 要注意的是,如果您在std :: initializer_list的许多项上运行,上述性能提供的解决方案并不是很好的讨价还价,因为
_init_list_with_square_brackets
以上建议类型的临时对象会反复创建。 Which again of course raises the wonder why this was not provided by the standard itself. 当然,这又再次引起了人们的疑惑,为什么标准本身未提供此功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.