`
tcspecial
  • 浏览: 913792 次
  • 性别: 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详解

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    C++中的`std::move`与`std::forward`:完美转发与移动语义的精髓

    std::move和std::forward是C++中处理左值和右值的强大工具。理解它们的区别和用途对于编写高效、可维护的C++代码至关重要。通过本文的详细解释和代码示例,读者应该能够更好地掌握这两个函数的使用方法,并在实际...

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

    `std::move`和`std::forward`是C++11引入的高效资源管理工具,用于提升性能,特别是处理移动语义和转发引用。现在,我们将详细探讨这些知识点。 首先,`cmake`是一个开源的,跨平台的自动化构建系统,用来管理项目...

    effective modern c++

    30. **`std::move`和`std::forward`**:了解何时使用`std::move`和`std::forward`来转移资源所有权。 31. **C++14的新特性**:如`std::make_unique`的实现在C++14中变得完整,`auto&&`的解引用推导,以及二进制字面...

    c++实用软件包(utility.h)

    虽然`&lt;functional&gt;`库提供了`std::bind`,但`utility`中的`std::placeholders`类命名空间包含了占位符`_1`, `_2`, ...,这些在与`std::bind`配合使用时,可以指定函数参数的位置。 7. **类型别名(Type Aliases)** ...

    c++ 线程池

    std::packaged_task(Args...)&gt; task(std::forward(func), std::forward(args)...); std::future&lt;return_type&gt; res = task.get_future(); { std::unique_lock&lt;std::mutex&gt; lock(queue_mutex); tasks.emplace(std...

    C++语言导学

    总的来说,《C++语言导学》涵盖了C++11和C++14的重要更新,包括智能指针、多线程、lambdas、move和forward等,这些都是现代C++程序员必备的知识。深入理解和掌握这些特性,不仅能提高编程效率,也能确保程序更加健壮...

    c++简单线程池的实现

    tasks_.push(Task(std::forward(func))); cond_.notify_one(); } private: void runWorker() { Thread worker; while (true) { Task task = dequeue(); if (!task) break; worker.enqueue(std::move(task)...

    Effective Modern C++(中文版).zip

    `std::move`和`std::forward`是实现移动语义的关键工具。 9. **类型推断**:C++11的`decltype`关键字可以根据表达式的类型推断出变量的类型,常用于泛型编程和模板元编程。 10. **`std::chrono`库**:提供了处理...

    编程语言C++的标准(14草案)

    例如,`std::move`和`std::forward`的使用更加灵活。 2. 自动类型推断的通用lambda表达式:C++14允许lambda表达式捕获变量按值,同时支持模板参数,使得lambda表达式更加强大,可以在更多的场合下作为通用函数对象...

    follow me to study modern c++.zip

    理解如何利用std::move和std::forward可以显著提升程序性能。 接着,深入探讨智能指针(Smart Pointers),如std::unique_ptr、std::shared_ptr和std::weak_ptr。它们自动管理内存,防止内存泄漏,使代码更安全。...

    Effective Modern C++.pdf

    该书涵盖了多个重要的话题,包括 braced 初始化、noexcept 规格、perfect forwarding、智能指针 make 函数、std::move、std::forward、rvalue 引用、universal 引用、lambda 表达式、std::atomic 和 volatile 等。...

    Effective.Modern.C++-42.Specific.Ways.to.Improve.Your.Use.of.C++11.and.C++14

    5. **std::move与std::forward的关系**:std::move用于将对象标记为“值可以被移动”,而std::forward则用于实现完美转发。作者解释了这两者之间的区别以及它们与右值引用和通用引用的关系。 6. **编写清晰、正确、...

    右值引用和移动语义1

    std::forward 和 std::move 是两个重要的函数模板,用于实现移动语义。 * std::forward 是一个类型转换函数,用于将参数转换为右值引用 * std::move 是一个类型转换函数,用于将参数转换为右值引用 六、应用场景 ...

    c++文档(包含c11汉化版本和英文版本)

    12. **新容器和算法**:如`std::array`作为固定大小的数组,`std::unordered_map`和`std::unordered_set`作为哈希表,以及`std::move`和`std::forward`等算法。 13. **智能指针(Smart Pointers)**:如`std::...

    Effective_Modern_C++_中文版

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

    Effective.Modern.C++11.pdf

    5. **std::move、std::forward、右值引用(rvalue references)和通用引用(universal references)**:这些是C++11的关键概念,书中深入剖析了它们之间的关系和各自的应用场景,帮助读者理解如何正确地移动和复制对象。...

    软件公司VC++编码设计规范.docx

    * 使用std::move和std::forward来提高性能。 6. 安全考虑 * 使用安全的字符串操作函数,例如std::string和std::wstring。 * 避免使用strcpy、strcat和sprintf函数。 * 使用安全的内存分配函数,例如new和delete。 ...

Global site tag (gtag.js) - Google Analytics