Ответ 1
Используйте ключевое слово inline
.
inline std::ostream& operator<< (std::ostream& o, const error_code& e) {
return o << "[" << e.hi << "," << e.lo << "]";
}
У меня есть следующий код в файле только заголовка.
#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 | (класс error_code const &, класс ViTrox:: error_code const &)" (?? U @@YA? AVerror_code @0 @ABV10 @0 @Z) уже определенный в xxx.obj
Я знаю, что могу решить эту проблему, если переместить определение operator<<
в файл cpp или в файл DLL.
Однако я просто хотел бы, чтобы они были в заголовочном файле SINGLE. Есть ли какая-либо техника для достижения такой цели? Или я должен отделить это определение от другого файла?
Используйте ключевое слово inline
.
inline std::ostream& operator<< (std::ostream& o, const error_code& e) {
return o << "[" << e.hi << "," << e.lo << "]";
}
Либо сделайте функцию 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 << "]";
}
Вы можете сделать функцию static
. Он задает внутреннюю связь, поэтому компоновщику будет все равно, если функция уже определена в других единицах перевода.
Или, как уже упоминалось, вы можете сделать это inline
. Он по-прежнему имеет внешнюю связь, но стандарт позволяет внешним встроенным функциям иметь определение в нескольких единицах перевода.
Определите эту функцию в файле .cpp(не в файле .h)
//yoursource.cpp
#include "yourheader.h"
std::ostream& operator<< (std::ostream& o, const error_code& e) {
return o << "[" << e.hi << "," << e.lo << "]";
}