问题
Previously asked questions (1 and 2) on SO seem to suggest that applying std::move
on elements of a std::initializer_list
may lead to UB. In fact, std::initializer_list
iterators prevent effective move because they refer to const elements. The reason is that compilers may use static read-only memory for storing the underlying array of an initializer_list.
I think this view is too limiting and I wanna know if experts out here agree. IMO, the following code cannot possibly use the read-only store.
void attempt_move(std::initializer_list<std::string> list) {
// must use const std::string &. Can't move.
}
int main(int argc, char *argv[])
{
if(argc >= 4)
attempt_move({ argv[1], argv[2], argv[3] });
}
The underlying std::string
array cannot possibly live in a read-only store because, AFAIK, read-only store must be initialized before main
and the argv
parameters are not known at that time. In fact, the C++11 standard says: "[ Note: The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer could be so allocated. —end note ]". Seems like this is one case where the "explicit array with the same initializer" cannot be allocated read-only. So it probably has automatic storage.
If that's true, seems like there are lost opportunities to move the string objects due to const iterators of std::initializer_list
. Is there a workaround?
回答1:
You can const_cast
away qualification if the underlying object isn't const
-qualified, but only the reference is.
But const
qualification isn't necessarily the same thing as being stored statically in physical ROM. In most cases, the compiler simply believes it's safe that the object won't be modified by anyone.
Yes, it's undefined behavior. And this is considered a serious shortcoming of initializer_list
. Hopefully it will be fixed for C++17.
Yes, you'll probably get away with it if moving is the only thing that ever happens to those elements, which in fact covers almost all the safe use-cases of initializer_list
under the sun.
来源:https://stackoverflow.com/questions/18821461/moving-elements-of-an-initialization-list-considered-dangerous