开发者

g++ "declaration of "operator<<" as non-function"

We have a custom Logging class which compiles fine in VisualStudio 2010, but throws errors when being compiled with g++ on Linux. The error message we receive are the following:

Logger.hpp:84: error: declaration of "operator<<" as non-function
Logger.h开发者_运维问答pp: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"

The respective lines of code are the following:

/*: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;
}

Other methods overloading the << operator work fine, therefore my guess is that the errors have something to with the argument type (std::_Smanip); any clues as to why?

Thanks, Ben


_Smanip is a Microsoft extension, and not part of the standard library. That's why your code compiles under Visual C++.

Here's an MSDN article on the use of _Smanip, and here's another one of how to avoid using it and write portable code instead.

EDIT: Found another link that explains manipulators with parameters in great detail. They discuss methods to implement custom ones as well.


I think the error message here is a little confusing, but the problem seems to be that _Smanip is not defined in GCC's libstdc++ (or at least it's not in my install of 4.6.0). Recall that in C++, any symbol starting with _ and a capital letter, or two __, represent implementation-reserved symbols, in this case what appears to be a VC extension. A related post to the gcc mailing list, suggesting that smanip was at one point in the C++98 draft, but later removed (and thus also removed from GCC's C++ runtime, which tends to track the ISO standard fairly strictly) - http://gcc.gnu.org/ml/gcc-help/2003-10/msg00385.html

You'll have to modify the code to use a different technique for GCC. Looking at libstdc++'s implementation of <iomanip> will probably help.


The error message really isn't very helpful at all on this. As pointed out by the other answers, _Smanip isn't an official part of the standard library, but I stumbled across this question due to the underlying problem.

Since _Smanip isn't a defined type, the GCC compiler (even in the latest versions) seems to interpret the definition of operator overloads (with parameters of undefined type) as declarations of class members. I happened to discover this by forgetting to include the template parameters for the base class when providing a derived class overload. Since the template parameters are part of the type name, what I was specifying as the parameter's type wasn't actually a defined type.

Just figured I'd share that for anyone else coming across this question. The solution is, of course, to make sure that your parameters have fully declared types when providing the declaration for the operator overload.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜