"std::forward"和"std::move"不生成代码是真的吗?

Is it true that "std::forward" and "std::move" do not generate code?

"std::forward"和"std::move"不生成代码是真的吗?我在《An Effective C++11/14 Sampler》中看到了这句话。相关代码在脚注中。有人可以详细解释代码吗?如果能对这个问题有所帮助,我将不胜感激。

根据文档 (https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00416_source.html),它说:

   /**
    *  @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); }

事实并非如此。它生成代码。代码

#include <utility>

int main() {
    int a;
    int b = std::move(a);
}

使用 Clang 10.0 生成此程序集(未优化):

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

和代码

#include <utility>

int main() {
    int a;
    int b = a;
}

使用 Clang 10.0 生成此程序集(未优化):

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

是否 "generates code" 取决于编译器及其设置。正如另一个答案所示,如果禁用优化。

,您可以期望生成一些额外的代码

std::movestd::forward 只是 return 对参数的引用,在运行时不需要任何操作(值类别的更改发生在编译时),如果启用了优化,任何半正经的编译器都不会为它们生成任何代码。

如果即使在调试版本中也不希望生成额外的代码,请使用 static_cast<T &&> 而不是那些函数。