简体   繁体   English

为什么`std :: initializer_list`不提供下标运算符?

[英]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. 假设您正在编写一个接受名为liststd::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: 我的猜测是这是以下原因之一:

  1. it's an omission, or 这是一个遗漏,或者
  2. because the initializer_list class is implemented with an array and you'd have to do bounds checking to provide safe access, it could more easily be used unsafely if that interface was provided, or 因为initializer_list类是用数组实现的,并且您必须进行边界检查才能提供安全的访问,所以如果提供了该接口,则可以更容易地不安全地使用它,或者
  3. to be consistent with the std algorithms iteration paradigm, or 与标准算法迭代范例保持一致,或
  4. because initializer_lists are, by their nature, ad-hoc, there's more room for error by addressing them directly 因为initializer_lists本质上是临时的,所以直接解决它们有更多的出错空间

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM