【问题标题】:About move a const object关于移动 const 对象
【发布时间】:2014-08-09 12:09:32
【问题描述】:

我知道std::move 一个常量对象实际上会调用T 的复制构造函数, 所以我想做一些实验来实现我的移动和内部删除以删除const,例如:

template<typename _Tp>
typename std::remove_const<typename std::remove_reference<_Tp>::type>::type&&
my_move(_Tp&& __t) noexcept {
    using removed_reference = typename std::remove_reference<_Tp>::type;
    using removed_ref_const = typename std::remove_const<removed_reference>::type;
    return static_cast<removed_ref_const&&>(__t);
}

但是这段代码不会编译?为什么

如果我更改remove_referenceremove_const 的顺序,这段代码会编译但不是我所期望的,my_move(const Object T) 仍然使用 Object T 的复制构造函数?

还有谁能给我一个正确的实现,当我删除const时会显示,这将使用T的移动构造函数。

T 可能为:

struct T
{
    T() = default;
    T(const T&) { std::cout << "copy ctor\n"; }
    T(T&&)      { std::cout << "move ctor\n"; }
};

int main() {
    const T t;
    T a = my_move(t);
}

【问题讨论】:

  • 好吧我没仔细看,但是如果你的代码修改了t的状态,那就错了,因为t是const。
  • 请告诉我们是什么让您认为尝试这样做是安全的。 move 将修改非常量源。这就是它的全部意义所在。如果可以修改该源,那么它首先不应该是 const 。请用您要解决的更高级别问题的描述来修改您的问题。也许这个潜在问题比您在此处提出的解决方案更好。

标签: c++ c++11 move-semantics


【解决方案1】:

要删除对象的常量,要使用的强制转换是 const_cast 而不是 static_cast

你想要类似的东西:

template<typename T>
T&& my_move(const T& t) noexcept {
    return std::move(const_cast<T&>(t));
}

(从对象中删除const 可能会出现问题)...

Live example

【讨论】:

  • 这个是直截了当的方式,但是在move的内部实现中怎么做呢?
  • 通过将 static_cast 更改为 const_cast 您的代码编译...但使用 const_cast 这种方式可能会导致 UB。
  • 这里发现remove_const只能移除顶层const,因为传给my_move的t是左值,解析为右值引用,所以可能remove_const不能移除const?
  • remove_const remove const for the type 而不是 value,所以在你的版本中你有 static_cast&lt;T&amp;&amp;&gt;(t) 其中tconst T&amp;.
  • 为什么使用 const_cast 可能会导致未定义的行为?
猜你喜欢
  • 2022-11-23
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多