一个initialization_list的移动元素被认为是危险的? [英] moving elements of an initialization_list considered dangerous?

查看:276
本文介绍了一个initialization_list的移动元素被认为是危险的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以前提出的问题( 1 2 )似乎建议应用<$ c $在 std :: initializer_list 的元素上的c> std :: move 可能会导致UB。事实上, std :: initializer_list 迭代器阻止有效移动,因为它们引用const元素。原因是编译器使用静态只读存储器来存储initializer_list的底层数组。

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.

我认为这个视图太限制了,我想知道这里的专家是否同意。 IMO,以下代码不能使用只读存储。

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] }); 
}

底下的 std :: string array不能存在于只读存储中,因为AFAIK只读存储必须在 main argv 参数当时不知道。事实上,C ++ 11标准说:[注意:如果一个具有相同初始化器的显式数组可以这样分配,实现可以在只读存储器中自由分配数组-end note]。看起来像这样的情况下,具有相同的初始化程序的显式数组不能分配只读。所以它可能有自动存储。

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.

如果这是真的,似乎失去了移动字符串对象的机会,因为 std :: initializer_list 。是否有解决方法?

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?

推荐答案

您可以 const_cast 底层对象不是 const -qualified,但只有引用。

You can const_cast away qualification if the underlying object isn't const-qualified, but only the reference is.

const 限定不一定是静态存储在物理ROM中的相同的东西。在大多数情况下,编译器只是认为对象不会被任何人修改是安全的。

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.

是的,它是未定义的行为。这被认为是 initializer_list 的严重缺点。希望它会固定为C ++ 17。

Yes, it's undefined behavior. And this is considered a serious shortcoming of initializer_list. Hopefully it will be fixed for C++17.

是的,如果移动是这些元素发生的唯一事情,你可能会放弃它实际上覆盖了太阳下 initializer_list 的几乎所有安全使用情况。

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.

这篇关于一个initialization_list的移动元素被认为是危险的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆