c++ - 生成一个拷贝作为采用右值引用的函数的输入

标签 c++ c++14 rvalue-reference

我有一个库函数(这里不在我的控制之下),它采用一个 r 值引用到可移动和可复制的类型 Bar:

void foo(Bar&& b);

在我自己的代码中,有时需要给它一个已有值的拷贝,比如

const auto b = getBar();
foo(mk_copy(b));
b.baz();

这是我想到的,

template<typename T> auto mk_copy(T val){return val;}

是否有标准方法或更常见的模式?甚至可能

template<typename T> auto mk_copy(T&& val){return std::forward<T>(val);}

或者,正如 pscill 指出的那样,只需再次写下类的名称,

foo(Bar(b));

但我不想重复类型名称。

最佳答案

对于内置类型,前缀 + 起到“复制”的作用:

void foo( char&& ) {}
void bar( double*&& ) {}

auto main() -> int
{
    char x{};
    foo( +x );

    double* p{};
    bar( +p );
}

不过,如果您将前缀 + 应用于其他类型,代码的读者可能会感到困惑,并且通用前缀 operator+ 模板可能最终会发生冲突带有一些类自己的前缀 operator+

因此,我建议使用现在明显的制造商命名约定,即 make 前缀。

然后它看起来像这样:

template< class Type >
auto make_copy( Type const& o ) -> Type { return o; }

您提出的第一个解决方案,

template<typename T> auto mk_copy(T val){return val;}

可能会复制值两次:首先复制到按值参数,然后复制到函数结果。

对于标准库容器这样的可移动类型,这不是问题,因为返回类型复制将减少为移动。但这对于较大的不可移动类型来说可能是个问题,因为在遗留代码中可能会出现这种情况。


第二种方案,

template<typename T> auto mk_copy(T&& val){return std::forward<T>(val);}

通过转发引用(又名通用引用)获取参数,然后从参数类型的重新创建中推导出返回类型。返回类型将始终是非引用,因为这是普通 auto 推导出的,所以这在技术上是正确的。但它不必要地复杂。

关于c++ - 生成一个拷贝作为采用右值引用的函数的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42349334/

相关文章:

c++ - 数组的正确值会提高性能吗?

c++ - 需要 Meyers Effective C++ Widget 右值实例讲解

c# - PCap性能

c++ - 编译错误递归链表

c++ - 如何模板化外部数组?

c++ - 当指针对象有可选参数时如何传递函数指针?

c++ - 通过右值引用返回更有效吗?

c++ - 从午夜开始获取纳秒级的最低延迟

c++ - Media Foundation 错误地将静止图像捕获流描述符标记为视频捕获

c++ - 嵌套结构的零初始化 - 编译器错误?