活动介绍
file-type

C++11新特性测试:std::move、std::forward与移动构造函数解析

版权申诉
61KB | 更新于2024-09-12 | 191 浏览量 | 5 下载量 举报 2 收藏
download 限时特惠:#14.90
"C++11中的std::move、std::forward、左右值引用以及移动构造函数是提升程序效率的关键特性。本文将通过实例代码详细解释这些概念,并进行性能测试,帮助读者深入理解其工作原理和应用场景。" 在C++11中,为了优化资源的移动和减少不必要的复制,引入了右值引用、std::move和std::forward。右值引用允许我们更高效地处理临时对象,而std::move和std::forward则是帮助我们安全地将对象从一个位置转移到另一个位置。 1. 右值引用(Rvalue Reference) 右值引用是一种特殊的引用类型,只能绑定到临时对象或即将销毁的对象上。在上面的代码示例中,`void funcA(A&& param)` 接受一个右值引用参数。当使用std::move(a)调用这个函数时,虽然std::move并没有改变a的内部状态,但它将a标记为可移动的,允许funcA的参数param直接访问a的资源,而不是创建一个副本。这在处理大对象时可以显著提高效率。 2. 左值引用和右值引用的区别 左值引用是常规引用,可以绑定到任何非临时对象。右值引用则只能绑定到临时对象。在重载函数时,我们需要明确区分这两种情况。例如: ```cpp void funcA(const A& param) // 接受左值和右值(但会隐式调用拷贝构造函数) void funcA(A& param) // 只接受左值引用 void funcA(A&& param) // 只接受右值引用 ``` 3. std::move和std::forward std::move用于将左值转换为可移动的右值,通常用于表示“我可以放弃这个对象的所有权”。然而,std::move并不保证实际的移动操作,它只是表明我们愿意这样做。在上面的示例中,std::move(a)使得funcA能够使用a的资源,而不是创建一个新的副本。 std::forward则用于转发参数,保留参数的左值/右值属性。它的用途在于模板函数,确保参数的性质在传递过程中不被改变。例如,如果一个函数接收一个模板参数并将其传递给另一个函数,std::forward能确保原始参数的左值/右值属性在传递过程中得到保留。 4. 引用折叠 当左右值引用与模板参数结合时,会出现引用折叠的现象。例如,`T&&`可以表示左值引用或右值引用,具体取决于T的类型。对于非模板函数,我们可以使用万能引用(`auto&&`)来编写能够接受任何类型引用的函数。 移动构造函数(Move Constructor)是C++11引入的一个重要特性,它允许类在创建新实例时直接借用旧实例的资源,而不是进行深拷贝。这样可以提高效率,特别是在处理大量数据或者复杂对象时。移动构造函数通常的形式为`T(T&& other)`,它接受一个右值引用作为参数,可以安全地从`other`中转移资源。 总结来说,C++11的这些新特性极大地提高了代码的效率,通过智能地移动而非复制对象,减少了不必要的开销。理解并熟练运用std::move、std::forward、左右值引用和移动构造函数,是每个C++开发者提高编程技能和代码性能的关键。

相关推荐

filetype

In file included from D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/hashtable_policy.h:34, from D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/hashtable.h:35, from D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/unordered_map.h:33, from D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/unordered_map:41, from D:/obj/i wanna own world to me/i wanna own world to me.cpp:9: D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/tuple: In instantiation of 'constexpr std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&}; long long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long long unsigned int ..._Indexes2 = {}; _T1 = const std::__cxx11::basic_string<char>; _T2 = SDL_GL_Image]': D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/tuple:2877:63: required from 'constexpr std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&}; _Args2 = {}; _T1 = const std::__cxx11::basic_string<char>; _T2 = SDL_GL_Image]' 2877 | typename _Build_index_tuple<sizeof...(_Args2)>::__type()) | ^ D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/stl_construct.h:97:14: required from 'constexpr decltype (::new(void*(0)) _Tp) std::construct_at(_Tp*, _Args&& ...) [with _Tp = pair<const __cxx11::basic_string<char>, SDL_GL_Image>; _Args = {const piecewise_construct_t&, tuple<__cxx11::basic_string<char, char_traits<char>, allocator<char> >&&>, tuple<>}; decltype (::new(void*(0)) _Tp) = pair<const __cxx11::basic_string<char>, SDL_GL_Image>*]' 97 | { return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/alloc_traits.h:536:21: required from 'static constexpr void std::allocator_traits<std::allocator<_Up> >::construct(allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image>; _Args = {const std::piecewise_construct_t&, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Tp = std::__detail::_Hash_node<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image>, true>; allocator_type = std::allocator<std::__detail::_Hash_node<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image>, true> >]' 536 | std::construct_at(__p, std::forward<_Args>(__args)...); | ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/hashtable_policy.h:2024:36: required from 'std::__detail::_Hashtable_alloc<_NodeAlloc>::__node_type* std::__detail::_Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _NodeAlloc = std::allocator<std::__detail::_Hash_node<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image>, true> >; __node_ptr = std::allocator<std::__detail::_Hash_node<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image>, true> >::value_type*]' 2024 | __node_alloc_traits::construct(__alloc, __n->_M_valptr(), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~ 2025 | std::forward<_Args>(__args)...); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/hashtable.h:312:35: required from 'std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::_Scoped_node::_Scoped_node(std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::__hashtable_alloc*, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Key = std::__cxx11::basic_string<char>; _Value = std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image>; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image> >; _ExtractKey = std::__detail::_Select1st; _Equal = std::equal_to<std::__cxx11::basic_string<char> >; _Hash = std::hash<std::__cxx11::basic_string<char> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, false, true>; std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::__hashtable_alloc = std::_Hashtable<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image>, std::allocator<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char> >, std::hash<std::__cxx11::basic_string<char> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::__hashtable_alloc]' 312 | _M_node(__h->_M_allocate_node(std::forward<_Args>(__args)...)) | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/hashtable_policy.h:870:42: required from 'std::__detail::_Map_base<_Key, std::pair<const _Key, _Val>, _Alloc, std::__detail::_Select1st, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>::mapped_type& std::__detail::_Map_base<_Key, std::pair<const _Key, _Val>, _Alloc, std::__detail::_Select1st, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits, true>::operator[](key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Val = SDL_GL_Image; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image> >; _Equal = std::equal_to<std::__cxx11::basic_string<char> >; _Hash = std::hash<std::__cxx11::basic_string<char> >; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<true, false, true>; mapped_type = SDL_GL_Image; key_type = std::__cxx11::basic_string<char>]' 870 | typename __hashtable::_Scoped_node __node { | ^~~~~~ D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/bits/unordered_map.h:992:20: required from 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = SDL_GL_Image; _Hash = std::hash<std::__cxx11::basic_string<char> >; _Pred = std::equal_to<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, SDL_GL_Image> >; mapped_type = SDL_GL_Image; key_type = std::__cxx11::basic_string<char>]' 992 | { return _M_h[std::move(__k)]; } | ~~~~^ D:/obj/i wanna own world to me/i wanna own world to me.cpp:164:57: required from here 164 | glBindTexture(GL_TEXTURE_2D, images["sprBrownBlock"s].textureID); | ^ D:/SelfUsing/Language/CLion 2025.1.3/mingw/lib/gcc/x86_64-w64-mingw32/14.2.0/include/c++/tuple:2888:9: error: no matching function for call to 'SDL_GL_Image::SDL_GL_Image()' 2888 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ D:/obj/i wanna own world to me/i wanna own world to me.cpp:43:14: note: candidate: 'SDL_GL_Image::SDL_GL_Image(const char*)' 43 | explicit SDL_GL_Image(const char* path) { | ^~~~~~~~~~~~ D:/obj/i wanna own world to me/i wanna own world to me.cpp:43:14: note: candidate expects 1 argument, 0 provided D:/obj/i wanna own world to me/i wanna own world to me.cpp:39:7: note: candidate: 'constexpr SDL_GL_Image::SDL_GL_Image(const SDL_GL_Image&)' 39 | union SDL_GL_Image { | ^~~~~~~~~~~~ D:/obj/i wanna own world to me/i wanna own world to me.cpp:39:7: note: candidate expects 1 argument, 0 provided ninja: build stopped: subcommand failed.

weixin_38571603
  • 粉丝: 3
上传资源 快速赚钱