好的
所以我有一个类,MyClass。我想用一个ints的向量来构造这个类。我想把这个向量移动到对象中。这个类是没有模板的。
class Myclass {
public:
Myclass (std::vector<int> && in) : vec{in} {};
Myclass (std::vector<int> & in) : vec{in} {};
private:
std::vector<int> vec;
}
在我的主文件中,我有
std::vector<int> orig (100);
Myclass A {orig};
std::cout << A.size() << '\n';
我希望将 "orig "移入 "A "后为空。在上面的任何一个选项中都不会发生这种情况,即使我做了
std::vector<int> orig (100);
Myclass A {std::move(orig)};
std::cout << A.size() << '\n'; // still prints 100
看来我可以通过
Myclass (std::vector<int> && in) : vec{std::move(in)} {}; // (1)
或
Myclass (std::vector<int> & in) : vec{std::move(in)} {}; // (2)
或
Myclass (std::vector<int> && in) : vec{std::forward<std::vector<int>(in)} {}; // (3)
我的问题是,为什么(1)的行为和(2)一模一样?
关于引用,rvalue和lvalue,需要记住的是它们是l值。 这意味着如果你对一个事物有一个引用,那么这个引用就是一个lvalue,你需要用 std::move
以将其投向一个r值,这样就可以移动它。
之间的真正区别是 Myclass (std::vector<int> && in)
和 Myclass (std::vector<int> & in)
是说,对于第一种情况,你必须使用
Myclass A {std::move(orig)};
// or
Myclass A {std::vector(100)};
而且不能传递一个l值给它,而对于second,你只能使用
Myclass A {orig};
因为它不会让你传递一个r值给它。
同时注意构造函数3是 "不正确的"。 你应该只使用 std::forward
当你有一个转发引用时。 std::vector<int> && in
是一个r值引用,而不是一个转发引用,所以你应该使用 std::move
来代替。 为了正确使用forward,你需要一个模板构造函数,如
template <typename T, std::enable_if_t<
std::is_same<std::decay_t<T>,
std::vector<int>>, bool> = true>
Myclass (T&& in) : vec{std::forward<T>(in)} {};