重载运算符主体只包含一个函数调用

时间:2017-08-23 13:30:12

标签: c++ c++11

我有这个功能

int add(T a, T b)
{
  return a.blah +b.blah;
}

我想重载加号运算符,我必须选择(当然,在这种情况下,加号运算符已经完成了以下代码所做的事情

选项1:

int operator+(T lhs, T rhs)
{
  return add(a,b);
}

选项2:

int operator+(T lhs, T rhs)
{
  return a.blah+b.blah;
}

这些定义中的任何一个是否具有优于另一个的性能优势?我想要实现的功能对STL容器的元素执行更复杂的操作。

2 个答案:

答案 0 :(得分:1)

使用选项1,不要重复自己。确保编译器在定义operator +时看到add的定义,以便它可以内联代码。打开优化后,生成的代码绝对没有区别。

struct T
{
    int blah;
};

int add(T a, T b)
{
  return a.blah +b.blah;
}

int operator+(T lhs, T rhs)
{
  return add(lhs, rhs);
}

GCC生成:

add(T, T):
  lea eax, [rdi+rsi]
  ret
operator+(T, T):
  lea eax, [rsi+rdi]
  ret

https://godbolt.org/g/g1ypni

Clang和Microsoft编译器生成相同的代码。

如果代码更复杂且编译器拒绝将add内联到operator+,请考虑使用operator +内联函数。然后它将被内联,因为它只进行一次调用,调用者将直接调用add而无需额外的开销。

通常的警告:你当然应该一如既往地进行基准测试,看看是否有任何真正的差异和配置文件,看看是什么导致了差异,同时查看生成的代码以检查优化是否按预期执行:-)

答案 1 :(得分:1)

选项1更好,因为您没有复制代码。

可能更好的是通过常量引用传递T来避免值复制。