C++ 将插入/安放从向量移动到向量本身
此代码应该打印C++ 将插入/安放从向量移动到向量本身,c++,gcc,visual-c++,stl,clang,C++,Gcc,Visual C++,Stl,Clang,此代码应该打印空的(Clang&GCC),还是不空的(visualc++) 如果我删除reserve(),这种情况会改变吗?使用emplace()而不是insert()怎么样 #包括 #包括 #包括 int main() { std::向量v; v、 reserve(10);//这是否会影响输出? v、 向后推(标准::使_共享(0)); v、 插入(v.begin(),std::move(v.front());//放置与插入有关系吗? printf(“元素0是:%s\n”,v[0]?“不是空的
空的
(Clang&GCC),还是不空的
(visualc++)
如果我删除reserve()
,这种情况会改变吗?使用emplace()
而不是insert()
怎么样
#包括
#包括
#包括
int main()
{
std::向量v;
v、 reserve(10);//这是否会影响输出?
v、 向后推(标准::使_共享(0));
v、 插入(v.begin(),std::move(v.front());//放置与插入有关系吗?
printf(“元素0是:%s\n”,v[0]?“不是空的”:“空的”);
返回0;
}
从逻辑上讲,notempty
对于insert
来说更有意义,因为insert
的调用方正在请求从特定对象移动,我们需要确保我们正从中移动。而且,reserve()
影响哪个元素在哪里结束似乎很愚蠢
然而,这意味着libstdc++(GCC)和libc++(Clang)都有缺陷,这似乎不太可能
也许更有趣的是,我对emplace
不太确定。我倾向于认为使用emplace
应该在逻辑上输出empty
,因为调用方请求在对象的正确位置(“emplace”)进行构造,这要求在构造之前进行移动
从容器移动到容器本身的正确行为是什么?它是否取决于调用insert
/emplace
/reserve
中哪一个的具体情况?它是实现定义的吗
不管它值多少钱 如果所需位置已被现有图元占用,则首先在另一个位置构造插入的图元,然后将其移动到所需位置
但这违背了GCC和Clang对
emplace
的要求,也违背了我的上述期望(这与我对插入的期望不同).可能insert
会在使用front
引用设置新值之前使其无效,从而导致代码具有未定义的行为?与shared\u ptr
无关,insert
会使front
返回的引用无效,引用什么并不重要,它仍然是未定义的行为。shared\u ptr
的从移动状态不是空的undefined@AlanBirtles:为什么insert
会使front
返回的引用无效?reserve
的全部目的不是为了避免这种情况吗?事实上,您可以检查它的地址,它仍然应该指向相同的位置。如果新的大小()大于旧的容量(),则不会导致重新分配。如果新的size()大于capacity(),则所有迭代器和引用都将无效。否则,只有插入点之前的迭代器和引用仍然有效。过去的结束迭代器也是无效的。
@AlanBirtles:非常有趣,我不知道引用在没有重新分配的情况下会失效。尽管如此,这在这里并不重要,因为你可以添加一个间接层次,你仍然会面临同样的困境。我会尝试更新这个问题,但它只会使问题变得(非常)复杂,而不会真正改变问题的实质。。。
#include <stdio.h>
#include <memory>
#include <vector>
int main()
{
std::vector<std::shared_ptr<int> > v;
v.reserve(10); // Should this affect the output?
v.push_back(std::make_shared<int>(0));
v.insert(v.begin(), std::move(v.front())); // Does 'emplace' vs. 'insert' matter?
printf("Element 0 is: %s\n", v[0] ? "not empty" : "empty");
return 0;
}