如何创建仅限标题的库?

Bil*_*eal 33 c++ header-only

我想将我正在处理的库打包为仅限标头的库,以便客户端更容易使用.(它很小,并且没有理由将它放入单独的翻译单元中)但是,我不能简单地将我的代码放在标题中,因为这违反了C++的一个定义规则.(假设库头包含在客户端项目的多个翻译单元中)

如何修改库以使其成为仅标题?

GMa*_*ckG 57

您可以使用inline关键字:

// header.hpp (included into multiple translation units)

void foo_bad() {} // multiple definitions, one in every translation unit :(

inline void foo_good() {} // ok :)
Run Code Online (Sandbox Code Playgroud)

inline 允许链接器简单地选择一个定义并丢弃其余的定义.

(因此,如果这些定义实际上不匹配,则会得到很好的未定义行为......!)


另外,在类类型中定义的成员函数被隐式标记inline:

struct myclass
{
    void i_am_inline_implicitly()
    {
        // because my definition is here
    }

    void but_i_am_not();
    void neither_am_i();
};

inline void myclass::but_i_am_not()
{
    // but that doesn't mean my definition cannot be explicitly inline
}

void myclass::neither_am_i()
{
    // but in this case, no inline for me :(
}
Run Code Online (Sandbox Code Playgroud)

  • 来自我的+1.这几乎是现代编译器的所有内联方法. (4认同)
  • @gil123:不。在 C++ 中,“内联”本质上不再与内联的实际优化技术有任何关系,这完全取决于编译器。它只是意味着“如果您多次看到这个函数定义,假设它们是相同的并选择一个”。如果没有内联,这将是一个重复定义错误。 (3认同)

Goz*_*Goz 7

使用标题保护,如Liz建议的那样,不要忘记在函数方法之前加入"inline".

#ifndef MY_HEADER_H_
#define MY_HEADER_H_

inline RetType FunctionName( ParamType1 param1, ParamType2 param2 )
{
    // Function body
    return retType;
}

#endif
Run Code Online (Sandbox Code Playgroud)

  • Nitpick:在 C++ 中,没有方法这样的东西。有成员函数和非成员函数。 (3认同)
  • @BillyONeal那不是真的;正如您在第587页的Stroustrups“ C ++编程语言”中所读到的那样,虚拟成员函数是“有时称为方法”。 (3认同)

Jer*_*ner 5

另外,我认为您需要避免在标头库代码中使用全局变量或静态变量。