`
tcspecial
  • 浏览: 895930 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

std::move与forward

阅读更多

 

一. std::move

c++11 提供了move语义,可以实现资源转移,提高系统性能。

 

源码实现:

/**
 *  @brief  Convert a value to an rvalue.
 *  @param  __t  A thing of arbitrary type.
 *  @return The parameter cast to an rvalue-reference to allow moving it.
 */
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }

 

std::remove_reference<U&>::type = U 移除类型中的引用

std::remove_reference<U&&>::type = U

static_cast<T&&>(t) 将表达式t转换为T类型右值,std::move只是将参数强制转换为右值引用。

 

区别左值和右值的快捷方式,看是否能对表达式取地址,如能则为左值,否则为右值。

如A a = GetA(); a为左值,GetA() 为右值。

class A
{
public:
    A() { std::cout << "Constructor" << std::endl; }
    A(const A&) { std::cout << "Copy Constructor" << std::endl; }
    //A(const A&&) { std::cout << "Move Constructor" << std::endl; }
    ~A() { std::cout << "Destructor" << std::endl; }
};

static A getA()
{
    A a;
    return a;
}

int main()
{
    A a = getA();	// 普通赋值
    //A&& a = getA();	// 右值引用
    return 0;
}

  

 添加-fno-elide-constructors 选项阻止编译器优化

$ g++ -o test test.cpp -fno-elide-constructors -std=c++11
Constructor
Copy Constructor
Destructor
Destructor

 通过右值引用,比之前少了一次拷贝构造和一次析构,原因在于右值引用绑定了右值,延长了临时右值的生存周期。

 

二. std::forward

源码实现:

// Forward an lvalue.
template<typename _Tp>
constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }

// Forward an rvalue.
template<typename _Tp>
constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
  static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
	    " substituting _Tp is an lvalue reference type");
  return static_cast<_Tp&&>(__t);
}

 

完美转发内部也是执行一个cast类型转换。

 

void printT(int &t)
{
	cout << "lvalue" << endl;
}

void printT(int &&t)
{
	cout << "rvalue" << endl;
}

template<class T>
void TestForward(T &&v)
{
	printT(v);
	printT(std::forward<T>(v));	// 参数转发
	printT(std::move(v));		// 强制转化为右值引用
}

// 调用
TestForward(1);

 

运行程序:

lvalue

rvalue

rvalue

1为右值,调用printT(v)时变为具名变量,即为左值,参数类型发生改变,则打印lvalue。

forward会按参数原有类型转发,则打印rvalue。

 

三. 函数包装器

template<class Function, class... Args>
inline auto FuncWrapper(Function &&f, Args&& ... args) -> decltype(f(std::forward<Args>(args)...))
{
	return f(std::forward<Args>(args)...);
}

// 调用
FuncWrapper(printT, 15);

 

参考链接:
std::move/forward详解

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    cmake 、代理模式与pimpl模式混用实例、std::move、std::forward()应用

    cmake 、代理模式与pimpl模式混用实例、std::move、std::forward()应用。用于学习C++设计模式,cmake程序编译。

    C++11中std::move、std::forward、左右值引用、移动构造函数的测试问题

    关于C++11新特性之std::move、std::forward、左右值引用网上资料已经很多了,我主要针对测试性能做一个测试,梳理一下这些逻辑,首先,左值比较熟悉,右值就是临时变量,意味着使用一次就不会再被使用了。...

    Effective_Modern_C++_中文版

    std::move、std::forward、右值引用和万能引用之间的联系 撰写整洁、正确以及高效的lambda表达式的方法 std::atomic和volatile有怎样的区别,它们分别用于什么场合,以及它们和C++的并发API有何联系 “旧”C++...

    Effective.Modern.C++.zip

    Topics include: The pros and cons of braced initialization, noexcept specifications, perfect forwarding, and smart pointer make functions The relationships among std::move, std::forward, rvalue ...

    modern-cpp:C ++在线课程。 有关现代C ++功能的模块。 C ++ 11,C ++ 14,C ++ 17和C ++ 20

    Nowoczesny C ++ using别名 统一初始化 default , delete , final , override 回顾 测试前答案 模数...移动语义的用法和属性 移动语义的实现 0、3、5的规则 std::move 参考崩溃 std::forward 复制省略 知识检查 回顾

    C++11在时空性能方面的改进

     新增的高效容器:array、forward_list以及unordered containers;  以及常量表达式、静态断言和move语义;  大小固定容器 array  std::array是一个支持随机访问且大小(size)固定的容器,它是c++11中新增...

    Effective Modern C++

    讲解std∷move,std∷forward,rvalue引用和全局引用之间的关联;介绍编写清晰、正确、高效lambda表达式代码的技巧;辨析std∷atomic和volatile之间的差异,它们各自该如何使用,还有它们与C++并行计算API之间的关联...

    Effective Modern C++学习笔记

    讲解std∷move,std∷forward,rvalue引用和全局引用之间的关联;介绍编写清晰、正确、高效lambda表达式代码的技巧;辨析std∷atomic和volatile之间的差异,它们各自该如何使用,还有它们与C++并行计算API之间的关联...

    Effective Modern C++:改善C++11和C++14的42个具体做法(中文版 + 英文版)

    讲解std∷move,std∷forward,rvalue引用和全局引用之间的关联;介绍编写清晰、正确、高效lambda表达式代码的技巧;辨析std∷atomic和volatile之间的差异,它们各自该如何使用,还有它们与C++并行计算API之间的关联...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

     16.2.6 理解std::move 610  16.2.7 转发 612  16.3 重载与模板 614  16.4 可变参数模板 618  16.4.1 编写可变参数函数模板 620  16.4.2 包扩展 621  16.4.3 转发参数包 622  16.5 模板特例化 624  小结 ...

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

     16.2.6 理解std::move 610  16.2.7 转发 612  16.3 重载与模板 614  16.4 可变参数模板 618  16.4.1 编写可变参数函数模板 620  16.4.2 包扩展 621  16.4.3 转发参数包 622  16.5 模板特例化 624  小结 ...

    Microsoft Library MSDN4DOS.zip

    STD Set Direction Flag STI Set Interrupt Flag STOS/STOSB/STOSW/STOSD Store String Data STR Store Task Register SUB Integer Subtraction TEST Logical Compare VERR, VERW Verify a Segment for Reading or ...

Global site tag (gtag.js) - Google Analytics