为什么在这个人为的示例中没有调用移动构造函数?
GetPerson 的未命名返回值不应该绑定到移动构造函数吗?
person.hpp
#ifndef PERSON_H
#define PERSON_H
#include <string>
struct Person {
Person(std::string name, int age) : name(name), age(age) {
std::cout << "ctor" << std::endl;
}
Person(const Person& rhs) : name(rhs.name), age(rhs.age) {
std::cout << "copy ctor" << std::endl;
}
Person(Person&& rhs) : name(std::move(rhs.name)), age(std::move(rhs.age)) {
std::cout << "move ctor" << std::endl;
}
~Person() {
std::cout << "dtor" << std::endl;
}
std::string name;
int age;
};
#endif
main.cpp
#include <iostream>
#include "person.hpp"
Person GetPerson(std::string name, int age) {
return Person(name, age);
}
int main(int argc, char* argv[]) {
Person p(GetPerson("X", 21));
}
我正在使用 gcc 版本 4.4.3 (Ubuntu 4.4.3-4ubuntu5) 并编译:
gcc -g -x c++ -lstdc++ -std=c++0x -o main ./main.cpp
RVO 或 NRVO 是原因吗?
Shouldn't the un-named return value from GetPerson bind to the move constructor?
person.hpp
#ifndef PERSON_H
#define PERSON_H
#include <string>
struct Person {
Person(std::string name, int age) : name(name), age(age) {
std::cout << "ctor" << std::endl;
}
Person(const Person& rhs) : name(rhs.name), age(rhs.age) {
std::cout << "copy ctor" << std::endl;
}
Person(Person&& rhs) : name(std::move(rhs.name)), age(std::move(rhs.age)) {
std::cout << "move ctor" << std::endl;
}
~Person() {
std::cout << "dtor" << std::endl;
}
std::string name;
int age;
};
#endif
main.cpp
#include <iostream>
#include "person.hpp"
Person GetPerson(std::string name, int age) {
return Person(name, age);
}
int main(int argc, char* argv[]) {
Person p(GetPerson("X", 21));
}
I'm using gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) and compiling with:
gcc -g -x c++ -lstdc++ -std=c++0x -o main ./main.cpp
Is RVO or NRVO the cause?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
RVO 启动并删除副本,并在
p
中构造GetPerson("X", 21)
。复制构造函数和移动构造函数都不需要被调用。如果您想在此处强制移动,那么
std::move(GetPerson("X", 21))
应该可以解决问题,但我不确定您为什么要这样做。RVO kicks in and elides the copy, and constructs
GetPerson("X", 21)
in place inp
. Neither the copy constructor nor the move constructor needs to be called.If you want to force a move here, then
std::move(GetPerson("X", 21))
should do the trick, but I'm not sure why you'd want to.是否调用移动构造函数并不重要。重要的是 COPY 构造函数没有被调用。
如果您的代码依赖于此处调用的移动构造函数,则根据
[class.copy]
p31,它会被破坏。Whether the move constructor is called or not is unimportant. What's important is that the COPY constructor is NOT called.
If your code relies on the move constructor being called here, it is broken, per
[class.copy]
p31.