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

时间:2011-01-05 01:55:13

标签: 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 << "]";
}

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

  

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

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

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

4 个答案:

答案 0 :(得分:17)

使用inline关键字。

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

答案 1 :(得分:7)

创建函数inline

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

或使其成为模板功能:

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 << "]";
}

答案 2 :(得分:3)

您可以使用static功能。它指定内部链接,因此链接器不关心函数是否已在其他转换单元中定义。

或者,如前所述,您可以将其设为inline。它仍然具有外部链接,但该标准允许外部内联函数在多个翻译单元中具有定义。

答案 3 :(得分:-1)

在.cpp文件中定义此函数(不在.h文件中)

//yoursource.cpp
#include "yourheader.h"

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