C++11:显式复制值以用作右值引用的最短方法

C++11: shortest way to explicitly copy a value to use as an rvalue reference

我有一个功能

class A { <has copy and move constructors > };

void f(A &&a) { ... }

我想用变量 x 调用函数 f,但我想 运行 fx 的副本上,而不是 x 本身。为什么我不能做这样的事情?

f(copy(x));

而是必须做

f(A(x));

有没有类似我上面描述的copy函数的东西?

注意:请不要告诉我添加执行复制的重载 f,我想要一些不需要重载并且是显式的(即 copy 明确说明到reader复制在这里完成)

这个呢?

template <typename T>
T copy(T t) {return t;}

当您按值传递 t 并进行后续移动时,复制完成。

http://coliru.stacked-crooked.com/a/cbc1a161f65a022b


如果你可以修改你的函数为:

void func(A) {}

那你就可以了

int main() {
   A a;
   func(a);            //copies
   func(std::move(a)); //moves
   return 0;
}

没有任何额外的构造函数调用。

http://coliru.stacked-crooked.com/a/1bc80bcce64f242f

使用拷贝构造函数怎么样? 你可以这样做:

A::A(const A &obj){
    //copy constructor here
}

// in external header
void copy(const A &obj){
    return A::A(obj);
}

玩得开心

女友

根据建议编辑

template<class T>
std::remove_cv_t<T> copy(T& t) {
  return t;
}
template<class T>
void copy(T&&)=delete; // block rvalue copy
template<class T, size_t N>
void copy(T(&)[N]) = delete; // we can implement this if we want: see below

将复制任何左值。在右值和不可复制类型(如数组)上,它将无法匹配或编译。

template<class T>
std::decay_t<T> copy_even_if_rvalue(T&& t) {
  return std::forward<T>(t);
}
namespace details {
  template<class T, size_t N, size_t...Is>
  std::array<T, N> copy_even_if_rvalue(T(&arr)[N], std::index_sequence<Is...>)
  {
    return {{arr[Is]...}};
  }
}
template<class T, size_t N>
std::array<T, N> copy_even_if_rvalue(T(&arr)[N]) {
  return details::copy_even_if_rvalue(arr, std::make_index_sequence<N>{} );
}
template<class T, size_t N>
std::array<T, N> copy_even_if_rvalue(T(&&arr)[N]) {
  return copy_even_if_rvalue(arr); // forward to lvalue version
}

将同时复制右值和左值。在我看来,通常 copycopy_even_if_rvalue 更聪明。

copy_even_if_rvalue 会将原始 C 数组转换为 std::arrays,因为这是复制它们的唯一合理方法。 =delete 重载是另一个合理的选择。

最短的方法就是f(A{x})

如果由于某种原因类型 A 太长或太丑而无法输入,那么这仍然比在全局范围内定义一个新函数要短:

f(std::decay_t<decltype(x)>(x));

或者没有 C++14 别名模板:

f(typename std::decay<decltype(x)>::type(x));