【问题标题】:Comparing address of std::endl比较 std::endl 的地址
【发布时间】:2011-01-20 03:28:02
【问题描述】:

我正在检查一段现有代码,发现它在使用 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&lt;&lt;() 以从流中去除 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&) );
};

【问题讨论】:

  • 您的源代码控制何时说测试已编写?可能当时 operator==() 不适用于这些类型。

标签: c++ function-pointers endl


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    有关信息:

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

    这意味着测试没有像我在问题中所说的那样出错。

    【讨论】:

      猜你喜欢
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 2021-01-10
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      相关资源
      最近更新 更多