C++11 是局部变量在C+中被视为右值的最后一次出现+;11?
局部变量在其作用域中的最后一次出现是否被视为右值?(就像在返回语句中一样。)例如,在下面的代码中,字符串是移动到向量中还是C++11 是局部变量在C+中被视为右值的最后一次出现+;11?,c++11,move-semantics,C++11,Move Semantics,局部变量在其作用域中的最后一次出现是否被视为右值?(就像在返回语句中一样。)例如,在下面的代码中,字符串是移动到向量中还是V.push_back(std::move(newitem))应该被显式写入 struct Element { std::string s1 {}; std::string s2 {}; } void f() { std::vector<Element> V; while (condition()) { Element newitem { };
V.push_back(std::move(newitem))
应该被显式写入
struct Element
{
std::string s1 {};
std::string s2 {};
}
void f()
{
std::vector<Element> V;
while (condition())
{
Element newitem { };
newitem.s1 = "example1";
newitem.s2 = "example2";
V.push_back(newitem);
};
};
struct元素
{
std::字符串s1{};
std::字符串s2{};
}
void f()
{
std::向量V;
while(条件())
{
元素newitem{};
newitem.s1=“example1”;
newitem.s2=“example2”;
V.推回(新项目);
};
};
在您的示例中,newitem
是一个左值(它是一个命名对象),因此不会使用move construtor。如果提供右值,编译器将使用移动构造函数,如中所示:
V.push_back(std::move(newitem))
其中xvalue被传递给push_back。因此,是的,您应该显式地使用
std::move
。否它不会自己调用std::move
。
您可以尝试以下代码:
#include <iostream>
#include <string>
#include <vector>
struct Element
{
std::string s1;
std::string s2;
Element() = default;
Element(const Element&) = default;
Element(Element&& other){
other.s1 = s1;
other.s2 = s2;
s1 = "";
s2 = "";
}
~Element()
{
std::cout << s1 << " " << s2 << std::endl;
}
};
void f()
{
auto V = new std::vector<Element>{}; // deny destucting the vector
V->reserve(10000); // deny reallocation
size_t i{ 0 };
while (i++<5)
{
Element newitem{};
newitem.s1 = "example1";
newitem.s2 = "example2";
V->push_back(newitem);
}
}
int main()
{
f();
std::getchar();
}
#包括
#包括
#包括
结构元素
{
std::字符串s1;
std::字符串s2;
元素()=默认值;
元素(常量元素&)=默认值;
元素(元素和其他){
其他1.s1=s1;
其他2.s2=s2;
s1=“”;
s2=“”;
}
~Element()
{
std::coutnewitem
有一个名称,因此只要您不使用std::move
它将被视为左值
有趣的是,在使用Visual studio 2013和/O2
构建此代码时,编译器没有优化任何调用。(您可以预期,由于没有人使用newitem
,因此编译器会将所有内容转换为就地构建)
就性能而言,您还可以使用安置_back
:
V.emplace_back(std::string("hello"),std::string("world"));
(std::string
包装器不是redandant)return大小写是特殊的,特别涉及到复制省略,而不是简单的移动语义(新对象直接在调用方空间中创建,而不是在本地构建移动
-ed)。否则,范围中的最终外观没有什么特别之处。