std :: ostream :: operator <<没有为std :: string定义?

luk*_*k32 3 c++ std stdstring ostream

我偶然发现了一个我无法理解的错误.

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

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

我看着在规范www.cplusplus.com确实也说,没有定义std::ostream::operator<<std::string作为参数.

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

错误源自以下行:

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

_sink因为std::ostream* 有一些包装功能,但它在这里打破了.

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

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

因为ostream& operator<< (ostream& out, const unsigned char* s );默认定义.

我只是看不出为什么它没有被自动猜测,因为它显然可以在简单的使用中工作cout << any_std_string.

不确定这是否相关,但我希望能够通过我的日志功能传递任何可以处理的内容std::ostream.我使用了明确的非模板化声明,但决定转向模板以log(const T& anything_to_log)重新进行重构.拥有5+超载似乎很愚蠢.当我尝试编译类似的东西时,我收到错误Log::log( std::string("test case") ).

它看起来像一些愚蠢的简单但我不能靠自己得到它.试图谷歌和搜索堆栈无济于事.

关于,luk32.

PS.我检查了解决方法并且它有效.为什么它没有隐含地完成?

ham*_*ene 9

operator <<重载不是成员ostream.例如,它们是独立的功能

ostream& operator << ( ostream& out, const basic_string<T>& bs );
Run Code Online (Sandbox Code Playgroud)

尝试

template<typename T> 
void Log::_log(const T& msg)
{  *_sink << msg;  }
Run Code Online (Sandbox Code Playgroud)


BoB*_*ish 5

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;
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是存储_sink作为参考,并按照通常的方式输出cout.