【问题标题】:Cannot std::cout an implicitly converted std::string不能 std::cout 隐式转换的 std::string
【发布时间】:2021-06-05 15:03:49
【问题描述】:

我以前用std::cout << str << std::endl显示字符串,认为隐式转换为std::string的对象也可以这样显示。

但是,我发现我错了。在我为 std::string 重载 operator << 之前,我不能 std::cout 隐式转换的 std::string

以下代码演示了上述内容。

#include <stdio.h>
#include <iostream>
#include <string>

class X
{
public:
    operator std::string() const {
        return std::string("world");
    }
};

#ifdef OVERLOAD_STREAM_OP
std::ostream& operator<<(std::ostream& os, const std::string& s) {
    return os << s;
}
#endif

int main() {
    std::string s = "hello";
    std::cout << s << std::endl; // viable
    printf("---\n");
    X x;
    std::cout << x << std::endl; // not viable

    return 0;
}

看起来,在 STL 实现中,std::string 类型的重载 operator &lt;&lt; 函数有点不同(但我真的不明白那些模板的东西):

  template<typename _CharT, typename _Traits, typename _Allocator>
    std::basic_ostream<_CharT, _Traits>&
    operator<<(std::basic_ostream<_CharT, _Traits>& __os,
           const basic_string<_CharT, _Traits, _Allocator>& __str)
    { return __os << __str._M_base(); }

我的问题:

  1. STL 重载的operator &lt;&lt; 和我自己重载的operator&lt;&lt; std::string 类型有什么区别?

  2. 为什么我不能用std::cout显示隐式转换的std::string对象x(编译错误)?

【问题讨论】:

  • 那个OVERLOAD_STREAM_OP 位,你怎么认为这是合法的?您正在添加一个重载,但没有一个类型是您的。

标签: c++ templates operator-overloading overload-resolution


【解决方案1】:
  1. STL 重载的operator &lt;&lt; 和我自己的 std::string 类型重载的operator&lt;&lt; 有什么区别?

你的operator&lt;&lt;是非模板的,而STL的是模板。

  1. 为什么我不能用std::cout显示隐式转换的std::string对象x(编译错误)?

template argument deduction 中不会考虑隐式转换(从Xstd::string),这会导致对模板operator&lt;&lt; 的调用失败。而非模板operator&lt;&lt;则没有这样的问题。

类型推导不考虑隐式转换(除了上面列出的类型调整):这是重载解析的工作,稍后会发生。

【讨论】:

    猜你喜欢
    • 2013-09-07
    • 2012-12-02
    • 1970-01-01
    • 2016-01-28
    • 2022-01-06
    相关资源
    最近更新 更多