带有标头实现的重复符号

时间:2012-11-19 03:57:09

标签: c++ compiler-construction build symbols

我有一个在头文件中声明和实现的C ++类。我选择这个是因为由于_GLIBCXX_DEBUG和预编译库,无法在Debug和Release版本之间轻松移动。例如,如果我定义_GLIBCXX_DEBUG,由于源文件中的ABI更改,Boost将崩溃。

仅标头实现产生了重复符号的问题。例如,在operator==下面的类中,非成员swap将生成多个定义的符号。

// Foo.hpp
namespace Bar
{
  template
  class Foo
  {
    ...
  };

  bool operator==(const Foo& a, const Foo& b) {
    ..
  }
}

namespace std
{
  template <>
  void swap(Bar::Foo& a, Bar::Foo& b)
  {
    a.swap(b);
  }
}

当声明和实现被拆分时,文件(Foo.hpp和Foo.cpp)编译并链接好了。

正确编译和链接的技巧是什么?

1 个答案:

答案 0 :(得分:6)

inline bool operator==(const Foo& a, const Foo& b) {
    ..
  }

成员函数是隐式内联的,前提是它们是在类中定义的。同样的事情对他们来说也是如此:如果他们可以毫不费力地被放入标题中,你确实可以这样做。

因为函数的代码被放入标题并且可见,所以编译器能够内联调用它们,即将函数的代码直接放在调用站点上(不是因为你在它之前放入内联函数)但更多的是因为编译器决定了这种方式。仅内联是对编译器的暗示。这可以带来性能提升,因为编译器现在可以看到参数匹配函数本地变量的位置,以及参数不会相互别名的地方 - 最后但并非最不重要的是,不再需要函数框架分配。