gpt4 book ai didi

C++ 编译器可以内联函数指针吗?

转载 作者:IT老高 更新时间:2023-10-28 12:51:29 25 4
gpt4 key购买 nike

假设我有一个函数 functionProxy,它接受一个泛型参数 function 并调用它的 operator():

template< typename Function > void functionProxy( Function function ) {
function();
}

传递给它的对象可能是:

  • 仿函数:

    struct Functor {
    void operator()() const {
    std::cout << "functor!" << std::endl;
    }
    };
  • 一个函数:

    void function( ) {
    std::cout << "function!" << std::endl;
    }
  • 一个 (C++0x) lambda 函数:

    [](){ std::cout << "lambda!" << std::endl; }

int main( )
{
functionProxy( Functor() );
functionProxy( function );
functionProxy( [](){ std::cout << "lambda!" << std::endl; } );
return 0;
}

在上述所有情况下,编译器能否将 function 内联到 functionProxy 中?

最佳答案

当然。

它知道function的值和它传给它的值是一样的,知道函数的定义,所以直接替换定义inline,直接调用函数。

我想不出编译器不会内联单行函数调用的情况,它只是用函数调用替换函数调用,没有可能的损失。


鉴于此代码:

#include <iostream>

template <typename Function>
void functionProxy(Function function)
{
function();
}

struct Functor
{
void operator()() const
{
std::cout << "functor!" << std::endl;
}
};

void function()
{
std::cout << "function!" << std::endl;
}

//#define MANUALLY_INLINE

#ifdef MANUALLY_INLINE
void test()
{
Functor()();

function();

[](){ std::cout << "lambda!" << std::endl; }();
}
#else
void test()
{
functionProxy(Functor());

functionProxy(function);

functionProxy([](){ std::cout << "lambda!" << std::endl; });
}
#endif

int main()
{
test();
}

定义 MANUALLY_INLINE 后,我们得到:

test:
00401000 mov eax,dword ptr [__imp_std::endl (402044h)]
00401005 mov ecx,dword ptr [__imp_std::cout (402058h)]
0040100B push eax
0040100C push offset string "functor!" (402114h)
00401011 push ecx
00401012 call std::operator<<<std::char_traits<char> > (401110h)
00401017 add esp,8
0040101A mov ecx,eax
0040101C call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40204Ch)]
00401022 mov edx,dword ptr [__imp_std::endl (402044h)]
00401028 mov eax,dword ptr [__imp_std::cout (402058h)]
0040102D push edx
0040102E push offset string "function!" (402120h)
00401033 push eax
00401034 call std::operator<<<std::char_traits<char> > (401110h)
00401039 add esp,8
0040103C mov ecx,eax
0040103E call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40204Ch)]
00401044 mov ecx,dword ptr [__imp_std::endl (402044h)]
0040104A mov edx,dword ptr [__imp_std::cout (402058h)]
00401050 push ecx
00401051 push offset string "lambda!" (40212Ch)
00401056 push edx
00401057 call std::operator<<<std::char_traits<char> > (401110h)
0040105C add esp,8
0040105F mov ecx,eax
00401061 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40204Ch)]
00401067 ret

没有,这个:

test:
00401000 mov eax,dword ptr [__imp_std::endl (402044h)]
00401005 mov ecx,dword ptr [__imp_std::cout (402058h)]
0040100B push eax
0040100C push offset string "functor!" (402114h)
00401011 push ecx
00401012 call std::operator<<<std::char_traits<char> > (401110h)
00401017 add esp,8
0040101A mov ecx,eax
0040101C call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40204Ch)]
00401022 mov edx,dword ptr [__imp_std::endl (402044h)]
00401028 mov eax,dword ptr [__imp_std::cout (402058h)]
0040102D push edx
0040102E push offset string "function!" (402120h)
00401033 push eax
00401034 call std::operator<<<std::char_traits<char> > (401110h)
00401039 add esp,8
0040103C mov ecx,eax
0040103E call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40204Ch)]
00401044 mov ecx,dword ptr [__imp_std::endl (402044h)]
0040104A mov edx,dword ptr [__imp_std::cout (402058h)]
00401050 push ecx
00401051 push offset string "lambda!" (40212Ch)
00401056 push edx
00401057 call std::operator<<<std::char_traits<char> > (401110h)
0040105C add esp,8
0040105F mov ecx,eax
00401061 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (40204Ch)]
00401067 ret

同样的。 (与 MSVC 2010 一起编译, Vanilla 版本。)

关于C++ 编译器可以内联函数指针吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4860762/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com