3

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

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

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

我查看了www.cplusplus.com上的规范,确实它说没有定义std::ostream::operator<<withstd::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 ); }

_sink被蔑视,因为std::ostream* 有一些包装功能,但它在这里中断。

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

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

因为有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。我检查了解决方法,它可以工作。为什么它没有隐式完成?

4

2 回答 2

9

operator <<重载不是ostream. 它们是独立的函数,例如

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

尝试

template<typename T> 
void Log::_log(const T& msg)
{  *_sink << msg;  }
于 2012-09-14T12:56:13.060 回答
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;
}

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

于 2012-09-14T12:59:59.033 回答