从const引用移动构造 [英] Move construction from const reference

查看:157
本文介绍了从const引用移动构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况,我需要从t1移动构造t2。
不幸的是,这是不可能的(constness违反我想)

什么是正确的方法来处理透明地从foo的调用者? (即不需要传递值和显式std :: move)

I have the following situation where I need to move construct t2 from t1. Unfortunately it is not possible to do that (constness violation I suppose)
What is the right approach to handle that transparently from the caller of foo ? (ie. without requiring a passing by value and an explicit std::move)

struct T
{
    T() = default;
    ~T() = default;
    T(T&&) = default;
};

T foo(const T& t) 
{
    T t3;

    if (predicate)
        return t3;
    else
        return std::move(t);
}

int main()
{
  T t1;
  T t2 = foo(t1);

  return 0; 
}


推荐答案

想要足够糟糕。为了做到这一点,你的 foo 将会基本上重新实现 std :: move

You could do this if you wanted to badly enough. To do it, your foo would end up as essentially a re-implementation of std::move.

struct T
{
    T() = default;
    ~T() = default;
    T(T&&) = default;
};

template<class T> struct my_remove_reference      {typedef T type;};
template<class T> struct my_remove_reference<T&>  {typedef T type;};

// The third part of a normal `remove_reference`, but which we don't need in
// this case (though it'll all still be fine if you un-comment this).
//template<class T> struct my_remove_reference<T&&> {typedef T type;};

template <typename T>
typename my_remove_reference<T>::type &&foo(T &&t) {
    return static_cast<typename my_remove_reference<T>::type &&>(t);
}

int main()
{
  T t1;
  T t2 = foo(t1);

  return 0; 
}



现在,尽管你可以/可以这样做,仍然或多或少是正确的 - 即使你可以做到,你几乎肯定不应该。如果你在支持移动构建的实际类中使用这个 foo (即,真正将状态从源移动到目标),你最终基本上会破坏你的源

Now, despite the fact that you can/could do this, the other answers remain more or less correct -- even though you can do it, you almost certainly shouldn't. If you used this foo on a real class that supports move construction (i.e., will really move the state from the source to the destination) you'd end up basically destroying your source object even though it remains visible.

使用您编辑的问题执行此操作,其中 foo 可以,但不会总是,破坏源对象将是特别是有害的。使用正确的名称,清楚地表明 foo 真的从源移动,它可以,可能,只是勉强这样做 - 但是(至少对我来说)一个可能或可能不会破坏其论证的函数似乎比那个可靠地更糟糕。显然,上面 foo 版本与 std :: move 是无意义的,但是一个版本也对输入做了一些其他处理(并且由于某种原因,不能与 std :: move 一起使用)可能,如果你真的没有别的选择,可能,只是几乎不能接受。

Doing this with your edited question, where foo could, but wouldn't always, destroy the source object would be particularly pernicious. With the right name that makes it clear that foo really moves from the source, it could, possibly, be just barely reasonable to do this -- but (at least to me) a function that might or might not destroy its argument seems drastically worse than one that does so dependably. Obviously, a version of foo like above that just does the same thing as std::move is pointless, but a version that also did some other processing on the input (and, for whatever reason, couldn't be used along with std::move) might, possibly, be just barely acceptable if you really didn't have any other choice.

这篇关于从const引用移动构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆