g ++ "объявление" оператора << "как не-функции" - PullRequest
4 голосов
/ 06 июля 2011

У нас есть собственный класс Logging, который прекрасно компилируется в VisualStudio 2010, но выдает ошибки при компиляции с g ++ в Linux.Мы получаем следующее сообщение об ошибке:

Logger.hpp:84: error: declaration of "operator<<" as non-function
Logger.hpp:84: error: expected ";" before "(" token
Logger.hpp:91: error: expected ";" before "inline"
Logger.hpp:91: error: declaration of "operator<<" as non-function
Logger.hpp:91: error: expected ";" before "(" token
Logger.hpp:98: error: expected ";" before "typedef"

Соответствующие строки кода следующие:

/*:84*/inline Logger& operator<<(std::_Smanip<std::ios_base::fmtflags> output)
{
        if (this->loggingEnabled())
                std::cout << output;
        return *this;
}

inline Logger& operator<<(std::_Smanip<std::streamsize> output)
{
        if (this->loggingEnabled())
                std::cout << output;
        return *this;
}

typedef std::basic_ostream<char, std::char_traits<char> >& (*StdEndl)(std::basic_ostream<char, std::char_traits<char> >&);
inline Logger& operator<<(StdEndl output)
{
        if (this->loggingEnabled())
                std::cout << output;
        return *this;
}

Другие методы, перегружающие оператор <<, работают нормально, поэтому я думаю,в том, что ошибки имеют отношение к типу аргумента (std::_Smanip);какие-либо подсказки, почему?

Спасибо, Бен

Ответы [ 3 ]

5 голосов
/ 06 июля 2011

_Smanip является расширением Microsoft и не является частью стандартной библиотеки. Вот почему ваш код компилируется под Visual C ++.

Вот статья MSDN об использовании _Smanip, а вот еще одна статья о том, как ее избежать и писать вместо этого переносимый код.

EDIT : Найдена еще одна ссылка , которая объясняет манипуляторы с параметрами в деталях. Они также обсуждают методы для реализации пользовательских.

4 голосов
/ 06 июля 2011

Я думаю, что сообщение об ошибке здесь немного сбивает с толку, но проблема, похоже, в том, что _Smanip не определено в libstdc ++ GCC (или, по крайней мере, его нет в моей установке 4.6.0). Напомним, что в C ++ любой символ, начинающийся с _ и заглавной буквы, или двух __, представляет зарезервированные для реализации символы, в данном случае это расширение VC. Связанное сообщение со списком рассылки gcc, предполагающее, что smanip был в какой-то момент в черновике C ++ 98, но позже удален (и, следовательно, также удален из среды выполнения C ++ GCC, которая имеет тенденцию довольно строго отслеживать стандарт ISO) - http://gcc.gnu.org/ml/gcc-help/2003-10/msg00385.html

Вам придется изменить код, чтобы использовать другую технику для GCC. Вероятно, поможет реализация <iomanip> в libstdc ++.

1 голос
/ 04 ноября 2012

Сообщение об ошибке действительно не очень помогает в этом.Как указано в других ответах, _Smanip не является официальной частью стандартной библиотеки, но я наткнулся на этот вопрос из-за основной проблемы.

Поскольку _Smanip не является определенным типом, Компилятор GCC (даже в самых последних версиях), по-видимому, интерпретирует определение перегрузок операторов (с параметрами неопределенного типа) как объявления членов класса .Я случайно обнаружил это, забыв включить параметры шаблона для базового класса при предоставлении перегрузки производного класса.Поскольку параметры шаблона являются частью имени типа, то, что я определял как тип параметра, на самом деле не было определенного типа.

Просто подумал, что поделюсь этим для всех, кто сталкивался с этим вопросом.Конечно, решение состоит в том, чтобы убедиться, что ваши параметры имеют полностью объявленные типы при предоставлении объявления для перегрузки оператора.

...