Я пытаюсь перегрузить operator<<
стандартным способом. У меня есть класс с именем SymbolTable, находящийся в файле с именем SymbolTable.h следующим образом:
namespace Compaler // It's a pun; don't ask
{
class SymbolTable
{
public:
// ...
friend ostream& operator<<(ostream &out, const SymbolTable &table);
private:
vector<map<int, Symbol*> > mSymbols;
};
// ...
}
Реализация operator<<
обеспечивает доступ к некоторым закрытым членам SymbolTable. Вот подпись реализации, чтобы продемонстрировать, что она не отличается от подписи предварительного объявления (я скопировал ее, чтобы быть уверенным, что не схожу с ума.)
ostream& operator<<(ostream &out, const SymbolTable &table)
{ ... }
Если я помещаю реализацию в SymbolTable.h, где находится второй ..., я получаю следующую ошибку компоновщика:
ld: дубликат символа Compaler :: operator << (std :: basic_ostream> &, Compaler :: SymbolTable const &) в /var/folders/kt/pl6qd1490fn3yqxfpg64jyr80000gn/T//ccstrYnU.o и / var / folder / kt /pl6qd1490fn3yqxfpg64jyr80000gn/T//ccDQFiyK.o для архитектуры x86_64
Однако, если я вместо этого положу его в SymbolTable.cpp
, где находятся остальные реализации моего члена SymbolTable, код даже не скомпилируется; Я получаю сообщения об ошибках при доступе к личным пользователям, указывающие, что дружба не распознается:
.. / SymbolTable / SymbolTable.h: В функции ‘std :: ostream & operator << (std :: ostream &, const Compaler :: SymbolTable &) ’:
../SymbolTable/SymbolTable.h:75: ошибка: 'std :: vector, std :: allocator>, Compaler :: Symbol *, std :: less, std :: allocator>>, std :: allocator, std: : allocator>, Compaler :: Symbol *>>>, std :: allocator, std :: allocator>, Compaler :: Symbol *, std :: less, std :: allocator>>, std :: allocator, std :: allocator>, Compaler :: Symbol *>>>>> Compaler :: SymbolTable :: mSymbols 'является частным
../SymbolTable/SymbolTable.cpp:98: ошибка: в этом контексте
Что я делаю не так?
Сводка ответов:
Благодаря Сету Карнеги и Дэниелу Р. Хиксу я понял это. В интересах любого, кто может совершить те же ошибки в будущем, я собираюсь обобщить ответы на мой вопрос, потому что в комментариях было много взад-вперед.
Первая (повторяющийся символ, когда реализация находилась в SymbolTable.h) возникла из-за того, что я пытался одновременно скомпилировать и связать два файла, которые включали SymbolTable.h. Я трудился из-за неправильного понимания того, как #ifdef
работают охранники; то есть они будут только препятствовать тому, чтобы код был включен дважды в один файл, но не помогут вам, если вы попытаетесь связать два файла, оба из которых включали код из третьего.
Вторая проблема заключалась в том, что я забыл поместить свою реализацию operator<<
в пространство имен Compaler, когда оно было в файле SymbolTable.cpp.