问题
Is it true that "std::forward" and "std::move" do not generate code? I saw this saying in << An Effective C++11/14 Sampler >>. The related code is at the footnote. Could somebody explain the code in detail? I would be very grateful to have some help with this question.
As per the documentation(https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00416_source.html), which says that:
/**
* @brief Forward an lvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
/**
* @brief Forward an rvalue.
* @return The parameter cast to the specified type.
*
* This function is used to implement "perfect forwarding".
*/
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);
}
/**
* @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); }
回答1:
Whether something "generates code" or not depends on the compiler and its settings. As the other answer shows, you can expect some extra code to be generated if the optimizations are disabled.
std::move
and std::forward
merely return a reference to the parameter, which doens't require any actions at runtime (the change in value category happens at compile-time), and if optimizations are enabled, any half-decent compiler will generate no code for them.
If you want no extra code to be generated even in debug builds, use a static_cast<T &&>
instead of those functions.
回答2:
That's not true. It generates code. The code
#include <utility>
int main() {
int a;
int b = std::move(a);
}
generates this assembly with Clang 10.0 (without optimization):
main: # @main
push rbp
mov rbp, rsp
sub rsp, 16
lea rdi, [rbp - 4]
call std::remove_reference<int&>::type&& std::move<int&>(int&)
xor ecx, ecx
mov edx, dword ptr [rax]
mov dword ptr [rbp - 8], edx
mov eax, ecx
add rsp, 16
pop rbp
ret
std::remove_reference<int&>::type&& std::move<int&>(int&): # @std::remove_reference<int&>::type&& std::move<int&>(int&)
push rbp
mov rbp, rsp
mov qword ptr [rbp - 8], rdi
mov rax, qword ptr [rbp - 8]
pop rbp
ret
and the code
#include <utility>
int main() {
int a;
int b = a;
}
generates this assembly with Clang 10.0 (without optimization):
main: # @main
push rbp
mov rbp, rsp
xor eax, eax
mov ecx, dword ptr [rbp - 4]
mov dword ptr [rbp - 8], ecx
pop rbp
ret
https://godbolt.org/z/DthcYe
来源:https://stackoverflow.com/questions/62359389/is-it-true-that-stdforward-and-stdmove-do-not-generate-code