Функции, впервые объявленные как friend
в классе, помещаются в окружающее пространство имен, поэтому определяемая вами функция должна быть определена в пространстве имен uiuc
.
Возможно, вы предполагаете, что если вы используете using namespace uiuc;
новые объявления / определения будут помещены в пространство имен uiuc
, но это не так. using namespace
влияет только на поиск имен, но не там, где размещаются объявления / определения.
Поэтому функция, которую вы определяете в данный момент, - это operator<<(std::ostream & os, uiuc::Game & game)
в области действия global пространства имен (которая не является friend
из uiuc::Game
), не operator<<(std::ostream & os, Game & game)
в пространстве имен uiuc
.
Поэтому вам необходимо правильно открыть пространство имен:
#include "game.h"
namespace uiuc {
std::ostream & operator<<(std::ostream & os, Game & game) {
for (unsigned long i = 0; i < game.stacks.size(); ++i) {
os << "Stack [" << i << "]: " << game.stacks[i] << std::endl;
}
return os;
}
}
Также, относительно ошибка компоновщика: если вы определяете friend
функцию вне определения класса и не указываете его как inline
, то это будет не встроенная функция , это означает, что для него может быть только одно определение только в одной единице перевода. Как правило, это не позволяет поместить определение в заголовок, поскольку заголовок обычно включается в несколько единиц перевода.
Если вы определяете функцию внутри тела класса или объявляете ее с помощью inline
ключевым словом, тогда это будет встроенная функция , означающая, что она должна быть определена в каждой единице перевода, использующей ее, что обычно означает, что определение должно быть помещено в заголовочный файл.