【发布时间】:2018-06-21 21:57:48
【问题描述】:
我不明白为什么在最后一种情况下是 在启用复制省略时调用移动构造函数(甚至是强制性的,例如在 C++17 中):
class X {
public:
X(int i) { std::clog << "converting\n"; }
X(const X &) { std::clog << "copy\n"; }
X(X &&) { std::clog << "move\n"; }
};
template <typename T>
X make_X(T&& arg) {
return X(std::forward<T>(arg));
}
int main() {
auto x1 = make_X(1); // 1x converting ctor invoked
auto x2 = X(X(1)); // 1x converting ctor invoked
auto x3 = make_X(X(1)); // 1x converting and 1x move ctor invoked
}
在这种情况下,哪些规则会阻碍移动构造函数被省略?
更新
调用移动构造函数时可能更直接的情况:
X x4 = std::forward<X>(X(1));
X x5 = static_cast<X&&>(X(1));
【问题讨论】:
-
你认为你的移动构造函数什么时候被调用?
-
@Pumkko 输出确实显示了移动构造函数调用cpp.sh/8lkmo
-
您是否仔细检查过您的编译器供应商可能对这个主题所说的话?我怀疑一些编译器可能会采用不同的方法来避免破坏遗留代码。
-
@SirGuy 我认为编译器在 C++17 中没有任何选项。我已经用
-std=c++1z尝试了 GCC 和 Clang。 (例如,x1和x2的初始化在 C++17 中是正确的,即使X的复制和移动 ctor 都被删除。)
标签: c++ language-lawyer move-semantics perfect-forwarding copy-elision