在头文件中有全局函数定义,避免重复的符号链接错误

Che*_*eng 10 c++

我在标题文件中有以下代码.

#pragma once

class error_code {
public:
    unsigned __int64 hi;
    unsigned __int64 lo;    
};

std::ostream& operator<< (std::ostream& o, const error_code& e) {
    return o << "[" << e.hi << "," << e.lo << "]";
}
Run Code Online (Sandbox Code Playgroud)

我得到链接错误,当项目中有2个cpp包含此头文件时.

错误LNK2005:"类error_code __cdecl运算符|(类error_code const&,类ViTrox :: error_code const&)"(?? U @@ YA?AVerror_code @ 0 @ ABV10 @ 0 @ Z)已在xxx.obj中定义

我知道如果我将定义移动operator<<到cpp文件或DLL文件,我可以解决这个问题.

但是,我只想将它们放在SINGLE头文件中.有没有什么技术可以做到这一点?或者我必须将定义分离到另一个文件?

Log*_*ldo 18

使用inline关键字.

inline std::ostream& operator<< (std::ostream& o, const error_code& e) {
    return o << "[" << e.hi << "," << e.lo << "]";
}
Run Code Online (Sandbox Code Playgroud)

  • @Nawaz,是的,为了优化的目的.但在这种情况下,我们正在利用它来指定联系. (4认同)
  • `inline`只是编译器的一个提示,它有时可能不会内联. (3认同)
  • 不是章节,不是IIRC,但是如果您没有“ inline”,则IIRC会违反ODR(如果您有inline但有两个或多个不同的主体,则它也会违反ODR)。 (2认同)
  • @Logan Capaldo:内联不会影响函数的链接.内联函数默认情况下仍然具有外部链接. (2认同)

wil*_*ell 7

要么使功能inline:

inline std::ostream& operator<< (std::ostream& o, const error_code& e) {
    return o << "[" << e.hi << "," << e.lo << "]";
}
Run Code Online (Sandbox Code Playgroud)

或使其成为模板功能:

template<class Ch, class Tr>
std::basic_ostream<Ch,Tr>& operator<< (std::basic_ostream<Ch,Tr>& o,
                                       const error_code& e) {
    return o << "[" << e.hi << "," << e.lo << "]";
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么模板也有效?内联模板? (2认同)