一. 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详解
相关推荐
std::move和std::forward是C++中处理左值和右值的强大工具。理解它们的区别和用途对于编写高效、可维护的C++代码至关重要。通过本文的详细解释和代码示例,读者应该能够更好地掌握这两个函数的使用方法,并在实际...
`std::move`和`std::forward`是C++11引入的高效资源管理工具,用于提升性能,特别是处理移动语义和转发引用。现在,我们将详细探讨这些知识点。 首先,`cmake`是一个开源的,跨平台的自动化构建系统,用来管理项目...
30. **`std::move`和`std::forward`**:了解何时使用`std::move`和`std::forward`来转移资源所有权。 31. **C++14的新特性**:如`std::make_unique`的实现在C++14中变得完整,`auto&&`的解引用推导,以及二进制字面...
虽然`<functional>`库提供了`std::bind`,但`utility`中的`std::placeholders`类命名空间包含了占位符`_1`, `_2`, ...,这些在与`std::bind`配合使用时,可以指定函数参数的位置。 7. **类型别名(Type Aliases)** ...
std::packaged_task(Args...)> task(std::forward(func), std::forward(args)...); std::future<return_type> res = task.get_future(); { std::unique_lock<std::mutex> lock(queue_mutex); tasks.emplace(std...
总的来说,《C++语言导学》涵盖了C++11和C++14的重要更新,包括智能指针、多线程、lambdas、move和forward等,这些都是现代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)...
`std::move`和`std::forward`是实现移动语义的关键工具。 9. **类型推断**:C++11的`decltype`关键字可以根据表达式的类型推断出变量的类型,常用于泛型编程和模板元编程。 10. **`std::chrono`库**:提供了处理...
例如,`std::move`和`std::forward`的使用更加灵活。 2. 自动类型推断的通用lambda表达式:C++14允许lambda表达式捕获变量按值,同时支持模板参数,使得lambda表达式更加强大,可以在更多的场合下作为通用函数对象...
理解如何利用std::move和std::forward可以显著提升程序性能。 接着,深入探讨智能指针(Smart Pointers),如std::unique_ptr、std::shared_ptr和std::weak_ptr。它们自动管理内存,防止内存泄漏,使代码更安全。...
该书涵盖了多个重要的话题,包括 braced 初始化、noexcept 规格、perfect forwarding、智能指针 make 函数、std::move、std::forward、rvalue 引用、universal 引用、lambda 表达式、std::atomic 和 volatile 等。...
5. **std::move与std::forward的关系**:std::move用于将对象标记为“值可以被移动”,而std::forward则用于实现完美转发。作者解释了这两者之间的区别以及它们与右值引用和通用引用的关系。 6. **编写清晰、正确、...
std::forward 和 std::move 是两个重要的函数模板,用于实现移动语义。 * std::forward 是一个类型转换函数,用于将参数转换为右值引用 * std::move 是一个类型转换函数,用于将参数转换为右值引用 六、应用场景 ...
12. **新容器和算法**:如`std::array`作为固定大小的数组,`std::unordered_map`和`std::unordered_set`作为哈希表,以及`std::move`和`std::forward`等算法。 13. **智能指针(Smart Pointers)**:如`std::...
std::move、std::forward、右值引用和万能引用之间的联系 撰写整洁、正确以及高效的lambda表达式的方法 std::atomic和volatile有怎样的区别,它们分别用于什么场合,以及它们和C++的并发API有何联系 “旧”C++...
5. **std::move、std::forward、右值引用(rvalue references)和通用引用(universal references)**:这些是C++11的关键概念,书中深入剖析了它们之间的关系和各自的应用场景,帮助读者理解如何正确地移动和复制对象。...
* 使用std::move和std::forward来提高性能。 6. 安全考虑 * 使用安全的字符串操作函数,例如std::string和std::wstring。 * 避免使用strcpy、strcat和sprintf函数。 * 使用安全的内存分配函数,例如new和delete。 ...