在此:
vector<pair<string,int>> vp;
string s;
int i;
while(cin>>s>>i) vp.push_back({s,i});
我对最后一行感到好奇。该对是在push_back
的调用中构建的,因此它被移动,而不是复制,是否正确?
如果它被写成了这样:
vector<pair<string,int>> vp;
string s= ...;
int i= ...;
pair<string,int> p{s,i};
vp.push_back(p);
虽然该对的构造涉及相同的资源,但现在该对被命名为p
,因此它不再是rvalue,因此不再使用移动语义,因此这是值传递,导致复制,对吗?
这对我来说意味着,在可能的情况下,在arg列表中构建对象是一种性能改进;任何人都可以验证吗?
答案 0 :(得分:6)
该对是在
>>> datetime(2016,10,1)-timedelta(1) datetime.datetime(2016, 9, 30, 0, 0)
的调用中构建的,因此它被移动,而不是复制,是否正确?
构造临时对,然后绑定到push_back
的右值引用参数。然后将其从该参数移到push_back
。
vector
相当于:
vp.push_back({s,i});
大致相当于:
vp.push_back(std::pair<std::string, int>{s, i});
你不需要临时使用rvalue引用重载。
您的第二个代码示例:
std::pair<std::string, int> p{s, i};
vp.push_back(std::move(p));
复制而不是移动,是的。请注意,无论哪种方式,我们仍然会将pair<string,int> p{s,i};
vp.push_back(p);
复制到对中(临时或s
)。因此,更好的方法是将p
移动到临时区域中:
s
或甚至没有开头的中间对:
vp.push_back({std::move(s), i});
这对我来说意味着,在可能的情况下,在arg列表中构建对象是一种性能改进;任何人都可以验证吗?
移动是一项性能改进,但您可以始终vp.emplace_back(std::move(s), i);
一个函数的参数 - 它不需要是临时的。在arg列表中构造会影响何时调用move-from对象的析构函数。
答案 1 :(得分:1)
你是对的。
在arg列表中构造对象是一种改进。
但是想一会儿。 int
无法移动。这是一份副本。通常std::string
会被移动,这样可以安全地进行malloc
/ new
次呼叫。
如果这一切都不影响可读性 - 那就去吧。否则,在大多数情况下,我认为它不会有如此大的改进。
我会建议一个&#34;方式&#34;
std::pair<std::string,int> p{s,i};
vp.push_back(std::move(p));
我建议甚至多一个&#34;方式&#34;
vp.emplace_back(std::move(s), i);
更新 - 我删除了问题中删除的cin
部分。