0

我有一个像这样的日志生成器类型:

Log Log::log(const int logLevel) 
{ 
    return Log(logLevel); 
}

Log& operator <<(Log& log, const char * s)
{
    if (log.hasLogLevel())
        log.out << s;
    return log;
}

我正在使用上面的代码,如下所示:

Log::log(1) << "Hello logger";

但是我收到了这些警告,直到最近我才意识到这是因为操作员超载的方式(或者至少这是我的想法)

warning C4239: nonstandard extension used : 'argument' : conversion from 'snow::Log' to 'snow::Log &'

我认为这会很好,因为它是一样的rvalue通过这些运算符重载传递/链接。我不认为这段代码在 MSVC++ 之外编译,我想知道我应该在这里做些什么不同的事情。

如果解决方案是简单地使用右值引用,那么我对此很满意,但我想更好地理解这里发生了什么。

4

1 回答 1

4

问题Log 是一个右值,并且不允许绑定到非常量引用参数。微软没有强制执行这一点,因为他们有一些会破坏的遗留代码。

如果您只想输出字符串,一种解决方法是让operator<<Log 类成为成员。您可以 调用右值的成员。

如果您想使用其他非成员运算符,您可以提供一个右值到左值转换器,就像 C++11 中的标准流一样。

就像是

template<class T>
Log& operator<<(Log&& log, const T& value)
{ return log << value; }

使用运算符内部log是一个左值并且可以绑定到其他运算符的非常量引用这一事实。

于 2012-10-26T11:43:47.483 回答