简体   繁体   English

为什么在 std::move 中使用 std::remove_reference ?

[英]Why is std::remove_reference used in std::move?

I tried implementing std::move , which uses std::remove_reference , however it seems to work without it.我尝试实现std::move ,它使用std::remove_reference ,但它似乎没有它。 Please give me an exemple in which my implementation fails, where std::remove_reference is necessary.请给我一个我的实现失败的std::remove_reference ,其中std::remove_reference是必要的。

template <class type> type && move(type & source) { return (type &&) source; }
template <class type> type && move(type && source) { return (type &&) source; }

Is std::remove_reference used only to avoid overloading std::move ? std::remove_reference仅用于避免重载std::move吗?

Here is a test class to help you :这是一个可以帮助您的测试类:

class test {
public :
    test() { }
    test(const test & source) { std::cout << "copy.\n"; }
    test(test && source) { std::cout << "move.\n"; }
};

Not a duplicate of How does std::move() transfer values into RValues?不是std::move() 如何将值传输到 RValues 的副本? because my question includes an exemple that seems to show that std::remove_reference is useless in this case + the sub-question.因为我的问题包括一个std::remove_reference ,该示例似乎表明std::remove_reference在这种情况下是无用的 + 子问题。

The implementation seems to work but both function declarations overlap.该实现似乎有效,但两个函数声明重叠。

 template <class type> type && move(type && source) { return (type &&) source; }

Here the type && source is interpreted as universal reference instead of r-value reference.这里type && source被解释为通用引用而不是 r 值引用。 Therefore, it can accept any input including l-value references and for l-value reference input it will return an l-value reference output - which is a potential issue.因此,它可以接受任何输入,包括左值引用,对于左值引用输入,它将返回一个左值引用输出——这是一个潜在的问题。

It is best avoided situations where multiple template function declaration can accept the same input as it can lead to variety of issues.最好避免多个模板函数声明可以接受相同输入的情况,因为它可能导致各种问题。 Although, perhaps there is a C++ standard rule that forces certain template function declaration called over the other when dealing with universal references.虽然,也许有一个 C++ 标准规则在处理通用引用时强制调用某些模板函数声明。 You'd need to ask a language lawyer for that info.你需要向语言律师询问这些信息。

You can make the move implementation with a single template function declaration using std::remove_reference as follows:您可以使用std::remove_reference使用单个模板函数声明进行移动实现,如下所示:

  template <class type>
  std::remove_reference_t<type> && move(type && source) 
  { 
      return (std::remove_reference_t<type>&&) source; 
  }

In general, std::remove_reference helps when dealing with universal references to figure out which type was given as input and obtaining some further information from it (although, one generally uses std::remove_cv_ref_t or equivalent).一般而言, std::remove_reference在处理通用引用时有助于找出作为输入给出的类型并从中获取一些进一步的信息(尽管通常使用std::remove_cv_ref_t或等价物)。

I tried implementing std::move, which uses std::remove_reference, however it seems to work without it.我尝试实现 std::move,它使用 std::remove_reference,但它似乎没有它。

Yes, it is working because you explicitly provided the overload for lvalue reference.是的,它正在工作,因为您明确提供了左值引用的重载。 While std::remove_reference is only relevant if you are using forwarding references.std::remove_reference仅在您使用转发引用时才相关。

If you take out this line: Godbolt如果你拿出这条线: Godbolt

template <class type> type && move(type & source) { return (type &&) source; }

And call your function as:并将您的功能称为:

test t2 = move(t1); //prints copy

To make this work, you will have to use std::remove_reference .要完成这项工作,您必须使用std::remove_reference Try on Godbolt :试试 Godbolt

template <class type>
std::remove_reference_t<type> && move(type && source)
{
    return
    static_cast<std::remove_reference_t<type>&& >(source);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM