比较 std::endl 的地址

发布于 2024-08-22 20:07:24 字数 1351 浏览 3 评论 0原文

我正在检查一段现有代码,发现使用 Visual C++ 9 和 MinGW 编译时它的行为有所不同:

inline LogMsg& LogMsg::operator<<(std::ostream& (*p_manip)(std::ostream&) )
{
    if ( p_manip == static_cast< std::ostream& (*)(std::ostream&) > ( &std::endl<char, std::char_traits<char> >) )
    {
        msg(m_output.str());
        m_output.str( "" );
    }
    else
    {
        (*p_manip) (m_output);            // or // output << p_manip;
    }
    return *this;
}

顾名思义,这是一个日志类,它重载 operator<<() 来从流中剥离 endls。

我发现了为什么它的行为不同:测试 p_manip == static_cast... 在 MinGW 中成功,而在 Visual C++ 9 中失败。MinGW

  • “忽略”强制转换并返回 的真实地址std::endl;
  • Visual C++ 9 实际上将指针转换为 endl 并返回不同的地址。

我将测试更改为 if ( p_manip == std::endl ) ,现在它的行为符合预期。

我的问题是:如此复杂(而且事实上是错误的)测试背后的基本原理是什么?


为了完整性:

class LogStream
{
public:
    LogStream() {}
protected:
    std::ostringstream m_output;
};

class LogMsg : public LogStream
{
    friend LogMsg& msg() ;
    static LogMsg s_stream;
public:
    LogMsg() {}
    template <typename T>
        inline LogMsg& operator<<(T p_data);
    inline LogMsg& operator<<(std::ostream& (*p_manip)(std::ostream&) );
};

I am inspecting a piece of existing code and found out it behaves differently when compiled with Visual C++ 9 and MinGW:

inline LogMsg& LogMsg::operator<<(std::ostream& (*p_manip)(std::ostream&) )
{
    if ( p_manip == static_cast< std::ostream& (*)(std::ostream&) > ( &std::endl<char, std::char_traits<char> >) )
    {
        msg(m_output.str());
        m_output.str( "" );
    }
    else
    {
        (*p_manip) (m_output);            // or // output << p_manip;
    }
    return *this;
}

As the name suggests, this is a log class and it overloads operator<<() to strip endls from the stream.

I found out why it behaves differently: the test p_manip == static_cast... succeeds with MinGW while it fails with Visual C++ 9.

  • MinGW "ignores" the cast and returns the real address of std::endl;
  • Visual C++ 9 actually casts the pointer-to-endl and returns a different address.

I changed the test to if ( p_manip == std::endl ) and now it behaves as expected.

My question is: what is the rationale behind such a complicated (and, as a matter of fact, wrong) test?


For the sake of completness:

class LogStream
{
public:
    LogStream() {}
protected:
    std::ostringstream m_output;
};

class LogMsg : public LogStream
{
    friend LogMsg& msg() ;
    static LogMsg s_stream;
public:
    LogMsg() {}
    template <typename T>
        inline LogMsg& operator<<(T p_data);
    inline LogMsg& operator<<(std::ostream& (*p_manip)(std::ostream&) );
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心的憧憬 2024-08-29 20:07:24

据猜测,我想说原作者没有意识到它们是兼容的类型,并且按照规范进行了转换(编译器没有要求他这样做)。

At a guess, I'd say the original author didn't realise they were compatible types, and did the conversion on spec (without the compiler requiring him to).

望喜 2024-08-29 20:07:24

有关信息:

语句 if ( p_manip == std::endl ) 无法在原始编译器(gcc 3.4.5,最初开发代码的编译器)上编译。

这意味着测试没有错误,正如我在问题中所说的那样。

For information:

The statement if ( p_manip == std::endl ) does not compile on the original compiler (gcc 3.4.5, the compiler on which the code was originally developed).

That means the test was not wrong as I stated in my question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文