【问题标题】:std::ostream::operator<< not defined for std::string?std::ostream::operator<< 没有为 std::string 定义?
【发布时间】:2023-03-21 16:20:02
【问题描述】:

我偶然发现了一个我无法理解原因的错误。

我认为它基本上归结为这个错误:

 error: no matching function for call to ‘std::basic_ostream<char>::operator<<(const std::basic_string<char>&)’

我查看了www.cplusplus.com 的规范,确实它说std::ostream::operator&lt;&lt; 没有以std::string 作为参数的定义。

我的问题是,当一个人写 std_ostream_instance &lt;&lt; std_fancy_string; 时会发生什么。我相信这是const char* 旁边最常见的调用之一(例如std::out &lt;&lt; std::string("Hello world!"))。

错误源于以下几行:

template<typename T> 
void Log::_log(const T& msg)
{  _sink->operator<<( msg ); }

_sink 被定义为 std::ostream* 有一些包装函数,但它在这里中断了。

我想我可以通过写作来解决问题

template<> 
void Log::_log<std::string>(const std::string& msg) {
  _sink->operator<<( msg.c_str() );
}

因为默认定义了ostream&amp; operator&lt;&lt; (ostream&amp; out, const unsigned char* s );

我只是看不出为什么它不会被自动猜到,因为它显然可以在 cout &lt;&lt; any_std_string 这样的简单用途中使用。

不确定这是否相关,但我希望能够通过我的日志函数传递std::ostream 无法处理的任何内容。我使用了显式的非模板化声明,但决定使用 log(const T&amp; anything_to_log) 的模板来重构它。有 5 次以上的重载似乎很愚蠢。当我尝试编译 Log::log( std::string("test case") ) 之类的内容时出现错误。

它看起来很简单,但我自己无法做到。尝试谷歌和搜索堆栈无济于事。

关于,luk32。

PS。我检查了解决方法,它可以工作。为什么它没有隐式完成?

【问题讨论】:

标签: c++ std stdstring ostream


【解决方案1】:

operator &lt;&lt; 重载不是ostream 的成员。它们是独立的函数,例如

ostream& operator << ( ostream& out, const basic_string<T>& bs );

试试

template<typename T> 
void Log::_log(const T& msg)
{  *_sink << msg;  }

【讨论】:

  • 工作。谢谢你。我认为ostream::operator&lt;&lt;() 会选择全局定义的版本。我的错。我的问题类似于operator&lt;&lt; (*_sink, msg); 这种情况,而编译器又看不到const char* 调用的定义。您的版本同时支持。
【解决方案2】:

std::string 版本不是成员函数,因此不能作为_sink 的成员调用。尝试以这种方式获取会员和非会员版本(事实上,无论如何您都不太可能需要会员版本):

#include <iostream>
#include <string>

int main()
{
    std::ostream * os = &std::cout;
    std::string s = "Hello\n";

    // This will not work
    // os->operator<<(s);
    (*os) << s;

    return 0;
}

或者更好的方法是将_sink 存储为参考,并完全按照您通常的方式输出到cout

【讨论】:

  • 谢谢。在问题下的评论中也有很好的参考。您的代码的另一个很好的例子是char* s2= "test2"; operator&lt;&lt; ( *os, s2);,它会失败。只有(*os) &lt;&lt; s 会同时通过。 hamstergene 是第一个回答的,所以我接受了他的。但这有很好的例子。
猜你喜欢
  • 1970-01-01
  • 2021-12-10
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 2013-07-28
  • 1970-01-01
相关资源
最近更新 更多