std命名空间中的operator<<是什么作用?

13

当然,以下代码可以工作(它调用std::cout::operator<<):

cout << 1 << '1' << "1" << endl;

发现了std::operator<<,看起来它只适用于char或char*参数:

operator<<(cout, '1'); // ok
operator<<(cout, "1"); // ok
operator<<(cout, 1);   // error

那么为什么我们需要这个运算符,如何使用它呢?

谢谢。


他们在§27.7.3.1。 - chris
2
如果你分析一下实际的错误信息,特别是"ambiguous"这个词的使用方式,那么理解起来可能会更有帮助。 - WhozCraig
1
@izuriel C++11标准。 - WhozCraig
仅供参考,这是标准的数字副本:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf - Brandon Buck
哪里?那就是我找到的。 - Brandon Buck
显示剩余3条评论
2个回答

7
operator<<(cout, '1'); // ok
operator<<(cout, "1"); // ok
operator<<(cout, 1);   // error

第一和第二个工作是因为它们调用了接受两个参数的非成员函数。接受charchar const*作为参数的函数被定义为非成员(自由)函数。
然而,接受int作为参数的函数被定义为成员函数,这意味着第三个函数需要调用一个成员函数。如果将其作为非成员函数调用,则int必须转换为某种类型,以便存在一个非成员函数。因此,在考虑此转换时,会导致歧义,因为有许多可能的转换同样好。
如上所述,这应该可以工作:
cout.operator<<(1); //should work

关于为什么有些函数被定义为成员函数,而有些则是非成员函数,我不知道答案。这需要对库的设计提案和决策进行大量研究。


我认为混淆更多的是为什么在std命名空间中甚至有一个operater<<的定义,而不是为什么它失败了。但是关于它为什么失败的信息很有用。 - Brandon Buck
1
+1,我同意这个分析。我也和楼主一样,不过我想知道为什么自由运算符只提供了 char、signed char 和 unsigned char 以及指向它们的指针,而没有其他类型的支持。 - WhozCraig
@WhozCraig 没错。这似乎是一种不一致性。 - user529758
1
@WhozCraig 我模糊地记得早期版本的C++运算符系统中没有任何成员运算符。那时你仍然使用<<。我的观点是,原因实际上可能纯粹与历史偶然有关... - Donal Fellows
同样,我也记得类似的事情。那是很久以前,当我还在上大学的时候,Turbo C++ 刚刚发布(这让我感到有点老了)。我曾经仔细研究过类似的库源代码。 - WhozCraig

0

我一直理解 charunsigned charchar* 被定义为非成员函数 basic_ostream 类之外的原因是为了更容易地重载它们。

你看,所有其他的 operator<< 都使用 char 作为构建块。因此,如果你想创建一个专门针对特定 charT 字符类型和 / 或 traits 特性类型的 ostream - 你只需要专门化这些 operator<< 函数。

如果它们是成员函数,你就必须专门化整个类(基本上重新创建所有类成员函数)。

我不确定这是唯一的原因,但这是我一直以来的看法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接