class 的移动成员作为常量引用参数传递
Moving members of class passed as a const reference argument
正在考虑:
template <typename... Args>
ResourceHolder& operator+=(const ResourceInserter<Key, Args...>& inserter) {
if constexpr (sizeof...(Args) == 0) {
insert(std::move(inserter.key),
std::move(inserter.fileName));
} else {
insert(std::move(inserter.key),
std::move(inserter.fileName),
std::move(std::get<Args...>(inserter.tuple)));
}
return *this;
}
您认为这是移动语义的正确用法吗?
ResourceInserter
的 inserter
实例作为常量引用传递。
移动 const 对象通常是一个简单的副本(除非你重载 Object(const Object&&)
)所以你对 std::move
的使用似乎没有用。
如果 ResourceInserter
的成员是(非常量)引用,
你的 const ResourceInserter&
是 "misleading",你的举动将实际发生。
没有。
你正在投射到 const Key &&
等等。Key::Key(const Key&&)
通常不能做任何有用的事情,所以你将被复制。
您可能想要一对重载
template <typename... Args>
ResourceHolder& operator+=(const ResourceInserter<Key, Args...>& inserter) {
if constexpr (sizeof...(Args) == 0) {
insert(inserter.key,
inserter.fileName);
} else {
insert(inserter.key,
inserter.fileName,
std::get<Args...>(inserter.tuple));
}
return *this;
}
template <typename... Args>
ResourceHolder& operator+=(ResourceInserter<Key, Args...>&& inserter) {
if constexpr (sizeof...(Args) == 0) {
insert(std::move(inserter.key),
std::move(inserter.fileName));
} else {
insert(std::move(inserter.key),
std::move(inserter.fileName),
std::move(std::get<Args...>(inserter.tuple)));
}
return *this;
}
从右值成员移动的位置inserter
与其名称相反,std::move doesn't actually move anything. It merely tells the compiler to try to move (i.e., indicate that an object t
may be "moved from" by casting it to rvalue reference type [more specifically, by producing xvalue expression])。
但是,您的 class 没有接受 const inserter&&
的构造函数,它将改为使用 class 的 copy constructor(隐式或显式),并且安全复制。没有危险,没有陷阱。如果复制构造函数因任何原因被禁用,你将得到一个编译错误。
试试这个:
#include <iostream>
struct Test {
Test() { }
Test(const Test& ) { std::cout << "COPY" << std::endl; }
Test(Test&&) { std::cout << "MOVE" << std::endl; }
};
int main()
{
const Test t;
Test t2 = std::move(t);
return 0;
}
打印 COPY
,而不是 MOVE
。
正在考虑:
template <typename... Args>
ResourceHolder& operator+=(const ResourceInserter<Key, Args...>& inserter) {
if constexpr (sizeof...(Args) == 0) {
insert(std::move(inserter.key),
std::move(inserter.fileName));
} else {
insert(std::move(inserter.key),
std::move(inserter.fileName),
std::move(std::get<Args...>(inserter.tuple)));
}
return *this;
}
您认为这是移动语义的正确用法吗?
ResourceInserter
的 inserter
实例作为常量引用传递。
移动 const 对象通常是一个简单的副本(除非你重载 Object(const Object&&)
)所以你对 std::move
的使用似乎没有用。
如果 ResourceInserter
的成员是(非常量)引用,
你的 const ResourceInserter&
是 "misleading",你的举动将实际发生。
没有。
你正在投射到 const Key &&
等等。Key::Key(const Key&&)
通常不能做任何有用的事情,所以你将被复制。
您可能想要一对重载
template <typename... Args>
ResourceHolder& operator+=(const ResourceInserter<Key, Args...>& inserter) {
if constexpr (sizeof...(Args) == 0) {
insert(inserter.key,
inserter.fileName);
} else {
insert(inserter.key,
inserter.fileName,
std::get<Args...>(inserter.tuple));
}
return *this;
}
template <typename... Args>
ResourceHolder& operator+=(ResourceInserter<Key, Args...>&& inserter) {
if constexpr (sizeof...(Args) == 0) {
insert(std::move(inserter.key),
std::move(inserter.fileName));
} else {
insert(std::move(inserter.key),
std::move(inserter.fileName),
std::move(std::get<Args...>(inserter.tuple)));
}
return *this;
}
从右值成员移动的位置inserter
与其名称相反,std::move doesn't actually move anything. It merely tells the compiler to try to move (i.e., indicate that an object t
may be "moved from" by casting it to rvalue reference type [more specifically, by producing xvalue expression])。
但是,您的 class 没有接受 const inserter&&
的构造函数,它将改为使用 class 的 copy constructor(隐式或显式),并且安全复制。没有危险,没有陷阱。如果复制构造函数因任何原因被禁用,你将得到一个编译错误。
试试这个:
#include <iostream>
struct Test {
Test() { }
Test(const Test& ) { std::cout << "COPY" << std::endl; }
Test(Test&&) { std::cout << "MOVE" << std::endl; }
};
int main()
{
const Test t;
Test t2 = std::move(t);
return 0;
}
打印 COPY
,而不是 MOVE
。