Why is `std :: initializer_list` often passed by value?

In almost every post I see on SO involving std::initializer_list , people tend to pass the value of std::initializer_list by value. According to this article:

http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

you need to pass a value if you need to make a copy of the transferred object. But copying std::initializer_list not a good idea since

Copy std::initializer_list does not copy base objects. The underlying array cannot exist after life, the initial object of the initializer list has ended.

So, why is an instance of it often passed by value, rather than, say, const& , which is guaranteed not to make an unnecessary copy?

+48
c ++ c ++ 11
Jul 23 '13 at 7:03
source share
2 answers

Its passed by value because its cheap. std::initializer_list , which is a thin shell, is most likely implemented as a pair of pointers, so copying is (almost) as cheap as passing by reference. In addition, they did not actually make a copy; as a rule, they made the transition, since in most cases the argument is built from a temporary one anyway. However, this does not affect performance - moving two pointers is as expensive as copying them.

On the other hand, access to the elements of the copy may be faster, since we avoid one additional dereferencing (links).

+42
Jul 23 '13 at 7:05
source share

Probably, for the same reasons, iterators are almost always passed by value: copying an iterator is considered "cheap." In the case of initializer_list there is also the fact that most instances will be temporary with trivial destructors, so the compiler can build them directly where it places the function argument without copying. Finally, there is the fact that, as iterators, the called function will probably want to change the value, which means that it would have to copy it locally if it were passed in with a reference to const.

EDIT:

Just to summarize: the standard library makes the assumption in general that it is better to pass iterators, initializer_lists, and function objects by value. As a result, you must make sure that any iterators, iterator_lists or function objects that you develop are cheap to copy, and you have to accept in your own code that they are cheap to copy. The traditional rule about when to use const references and when to use a value should probably be changed to reflect this:

Use pass by reference to const for class types other than iterators, initializer_lists, or function objects; otherwise use pass by value.

+8
Jul 23 '13 at 8:09
source share



All Articles