Я пишу небольшую матричную библиотеку на C ++ для матричных операций. Однако мой компилятор жалуется, где раньше этого не было. Этот код оставлялся на полке в течение 6 месяцев, и между тем я обновил свой компьютер с debian etch до lenny (g ++ (Debian 4.3.2-1.1) 4.3.2), однако у меня та же проблема в системе Ubuntu с тем же g ++ ,
Вот соответствующая часть моего класса матрицы:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
И «реализация»:
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Это ошибка, выданная компилятором:
matrix.cpp: 459: ошибка: 'std :: ostream & Math :: Matrix :: operator << (std :: ostream &, const Math :: Matrix &)' должен принимать ровно один аргумент
Я немного сбит с толку этой ошибкой, но опять же мой C ++ стал немного ржавым после того, как я много работал за те 6 месяцев. :-)
источник
operator<<
должны быть в пространстве именMath
? Кажется, это должно быть в глобальном пространстве имен. Я согласен, что мой компилятор хочет, чтобы он был в пространстве именMath
, но это не имеет смысла для меня.Просто скажу вам еще об одной возможности: мне нравится использовать для этого определения друзей:
Функция будет автоматически нацелена на окружающее пространство имен
Math
(даже если ее определение присутствует в области действия этого класса), но не будет видимой, если вы не вызовете operator << с объектом Matrix, который сделает поиск с зависимым аргументом для поиска этого определения оператора. Иногда это может помочь с неоднозначными вызовами, поскольку он невидим для типов аргументов, отличных от Matrix. При написании его определения вы также можете напрямую ссылаться на имена, определенные в Matrix, и на саму Matrix, не квалифицируя имя с некоторым возможно длинным префиксом и предоставляя такие параметры шаблона, какMath::Matrix<TypeA, N>
.источник
Чтобы добавить в ответ Mehrdad,
В вашей реализации
источник
Предполагая, что мы говорим о перегрузке
operator <<
для всех классов, производных от класса,std::ostream
для обработкиMatrix
класса (а не о перегрузке<<
дляMatrix
класса), имеет смысл объявить функцию перегрузки вне пространства имен Math в заголовке.Используйте функцию друга, только если функциональность не может быть достигнута через общедоступные интерфейсы.
Matrix.h
Обратите внимание, что перегрузка оператора объявляется вне пространства имен.
Matrix.cpp
С другой стороны, если ваша функция перегрузки делает нужно быть друг то необходим доступ к частным и защищенным членам.
math.h
Вам нужно заключить определение функции в блок пространства имен, а не просто
using namespace Math;
.Matrix.cpp
источник
В C ++ 14 вы можете использовать следующий шаблон для печати любого объекта, который имеет T :: print (std :: ostream &) const; член.
В C ++ можно использовать 20 концепций.
источник
std::ostream&
, так как это тип возврата в любом случае?