考虑下面的代码,它试图移动构造一个shared_ptr
,但是由于出现错误而出现了复制构造它:
#include <utility>
#include <cassert>
#include <memory>
int main()
{
const auto x=std::make_shared<int>(4325); // can't be moved from
const std::shared_ptr<int> y(std::move(x)); // silently copy-constructs
assert(x==nullptr); // fails
}
此处由于x
为const
,y
复制构造而非移动构造的事实将仅在运行时检测到。有没有办法确保移动真的发生,在编译时?
答案 0 :(得分:3)
您可以编写一个检查器,以查看是否可以从以下位置移动表达式:
template <typename T>
constexpr bool can_be_moved (T&&) {
return !std::is_reference<T>{} && !std::is_const<T>{};
}
然后您可static_assert
std::move(x)
可以移动:
int main()
{
const auto x=std::make_shared<int>(4325);
const std::shared_ptr<int> y(std::move(x));
static_assert(can_be_moved(std::move(x)), "x must be able to be moved from");
}
我确实不太确定这在实践中有多大用处。除非你知道这个类的构造函数是做什么的,否则你仍然无法保证某些东西真正被移除。