代码之家  ›  专栏  ›  技术社区  ›  Hatted Rooster

把时间投入到怪异的行为中

  •  1
  • Hatted Rooster  · 技术社区  · 7 年前

    stream << "test";
    

    同:

    stream.operator<<("test");
    

    #include <iostream>
    #include <iomanip>
    #include <ctime>
    
    int main() 
    {
       std::ostream s {std::cout.rdbuf()};
       auto t = std::time(nullptr);
       auto tm = *std::localtime(&t);
       s.operator<<(std::put_time(&tm, "%H:%M:%S"));//doesn't work
       return 0;
    }
    

    在改变 doesn't work 行至:

    s << std::put_time(&tm, "%H:%M:%S");
    

    在C++ 14上的GCC和MSVC 2017似乎都会产生错误。这是编译器错误还是这两个语句不相等?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Rakete1111    7 年前

    这是你的代码,但减少了:

    struct X { friend void operator+(X, X); };
    
    int main() {
      X var;
      var + var; // ok
      var.operator+(var); // fail
    }
    

    问题是,通过显式调用 operator<< ,您所依赖的事实是它确实是类的运算符(例如 T& T::operator<<(const U&); var.operator<<(/*...*/) ).

    如果你写信 var << something

    运算符可以在类之外定义,因为 std::put_time [ext.manip] :

    未指定类型的对象,如果 out basic_­ostream<charT, traits> 那么这个表达式 out << put_­time(tmb, fmt) 表现得好像它叫 f(out, tmb, fmt) ,其中函数 f 定义为:[…]

    因为要求的形式 var << var2 ,没有任何东西禁止标准库实现在类之外定义它,以便使用ADL找到它。