运算符可以识别右值吗

Can an operator to recognize rvalue?

本文关键字:识别 运算符      更新时间:2023-10-16

我有一些STL容器类型T,比如template< typename F > using T = std::vector< F >;。我想能够写以下代码:

typedef std::string F;
T< F > v(2, "a"), w(3, "b");
v += std::move(w);
std::cout << "v : ";
std::copy(std::begin(v), std::end(v), std::ostream_iterator< F >(std::cout, "|"));
std::cout << std::endl << "w : ";
std::copy(std::begin(w), std::end(w), std::ostream_iterator< F >(std::cout, "|"));
std::cout << std::endl;

并得到输出:

v : a|a|b|b|b|
w : |||

也就是说,我希望能够通过"std::move-ing"(从<utility>一个接一个或从<algorithm>按范围)将源w的所有内容附加到目标v的末尾,这样源的所有元素都保持为空,只需要w.clear();调用。

是否可以让操作员识别右值引用?说:

T & ::operator += (T &, T &&);

或者我还想要什么?

是的,这会起作用,但T不是一种类型,所以不能这样写运算符。T是一个模板,所以操作员需要像一样

template<typename U>
  T<U>& operator+=(T<U>&, T<U>&&);

一种可能的实施方式是:

template<typename U>
  T<U>& operator+=(T<U>& lhs, T<U>&& rvalue)
  {
    std::move(rvalue.begin(), rvalue.end(), std::back_inserter(lhs));
    rvalue.clear();
    return lhs;
  }

并且对于lvalues:过载

template<typename U>
  T<U>& operator+=(T<U>& lhs, const T<U>& lvalue)
  {
    std::copy(lvalue.begin(), lvalue.end(), std::back_inserter(lhs));
    return lhs;
  }

要使它适用于任何类型(我认为这是一个坏主意,应该将其限制为只匹配您想要的类型),请尝试以下操作:

template< class T, class U >
  inline
  typename std::enable_if< std::is_lvalue_reference< U >::value, T& >::type
  operator += (T& lhs, U&& lvalue)
  { /* copy from lvalue */ }
template< class T, class U >
  inline
  typename std::enable_if< !std::is_lvalue_reference< U >::value, T& >::type
  operator += (T& lhs, U&& rvalue)
  { /* move from rvalue */ }