内联和静态函数调用操作符

时间:2013-02-11 08:37:59

标签: c++ templates inline functor

我有一个由模板参数T参数化的函数模板,根据实例化的T给出不同的行为。所需的具体变化非常简单,对静态函数T::foo(some_args)的调用就足够了,因为不涉及任何状态。

但是我不希望foo出现在功能模板的主体中。

我宁愿打电话给T(some_args);以避免语法噪音。我认为将函数调用操作符()声明为静态是不可能的(或者是吗?)。 T没有状态,因此没有特定于实例的变量。

如果无法实现上述目标,那么更有可能获得内联/优化(在G ++,Clang,ICC中)

T::foo(some_args); // foo being a static function

T()(some_args);  // operator () declared inline

我不知道装配检查输出,问题更多来自学术/好奇心的观点而非实际表现。

T()(some_args)是否真的在运行时分配对象?或者它是否通常被优化掉了?

1 个答案:

答案 0 :(得分:3)

简单示例:

struct T
{
    int operator()(int i) const {
        return i+1;
    }   
};

int main()
{
    return T()(1);
}

用-O2编译,这将产生:

(gdb) disassemble main
Dump of assembler code for function main():
   0x0000000000400400 <+0>:     mov    eax,0x2
   0x0000000000400405 <+5>:     ret
End of assembler dump.

即使使用-O0,如果在T中使用隐式默认构造函数,也不会创建临时值:

(gdb) disassemble main
Dump of assembler code for function main():
   0x00000000004004ec <+0>:     push   rbp
   0x00000000004004ed <+1>:     mov    rbp,rsp
   0x00000000004004f0 <+4>:     sub    rsp,0x10
   0x00000000004004f4 <+8>:     lea    rax,[rbp-0x1]
   0x00000000004004f8 <+12>:    mov    esi,0x1
   0x00000000004004fd <+17>:    mov    rdi,rax
   0x0000000000400500 <+20>:    call   0x400508 <T::operator()(int) const>
   0x0000000000400505 <+25>:    leave
   0x0000000000400506 <+26>:    ret
End of assembler dump.