c++ - put_time 进入流奇怪的行为

标签 c++ stream c++14

据我了解,重载运算符会被编译器翻译成方法调用,例如:

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 似乎都会产生错误。这是编译器错误还是这两个语句不相等?

最佳答案

这是您的代码,但已简化:

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 ,然后除了类中定义的运算符外,查找(称为 ADL)还会查找类外定义的运算符。

运算符可以在类之外定义,因为std::put_time的返回类型指定为 ( [ext.manip] :

An object of unspecified type such that if out is an object of type basic_­ostream<charT, traits> then the expression out << put_­time(tmb, fmt) behaves as if it called f(out, tmb, fmt), where the function f is defined as: [...]

因为需求的形式是var << var2 ,没有什么可以禁止标准库实现在类之外定义它,以便使用 ADL 找到它。

关于c++ - put_time 进入流奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51832251/

相关文章:

c++ - qmake 自动生成的 Makefile 编译器设置不正确

c++ - 分段故障运行 boost 示例

以 ~ 开头的 C++ 路径

c++ - 友元函数和命名空间。无法访问类中的私有(private)成员

c++ - OpenCV : How to display webcam capture in windows form application?

c# - 为什么此代码中的流保持打开状态?

firebase - 如何在不重置状态的情况下更新 StreamBuilder 中的 Flutter Cards?

c# - 如何在 C# 中将音频流式传输到扬声器

visual-studio-2013 - MS Visual Studio 2013 中没有 <optional> - 该怎么办?

c++ - 如何避免在 BFS 中进一步搜索顶点的邻居?我正在使用 Boost 图形库