覆盖按位运算符时的 MISRA 警告

MISRA warning when overriding bitwise operator

我为日志接口编写了一个简单的包装器,因此我可以使用左移运算符<<来打印日志。

logger_wrapper.h

class LoggerWrapper
{
public:

    LoggerWrapper(logging::LoggerInterface *logger, logging::LogPriority priority);

    ~LoggerWrapper();

    bool log_enabled();

    std::stringstream& get_stream();

private:

    std::stringstream stream_;

    logging::LoggerInterface *logger_;

    logging::LogPriority priority_;
};


template <typename T>
LoggerWrapper& operator<<(LoggerWrapper& record, T&& t) {
    if (record.log_enabled())
    {
        record.get_stream() << std::forward<T>(t);
    }
    return record;
}

template <typename T>
LoggerWrapper& operator<<(LoggerWrapper&& record, T&& t)
{
    return record << std::forward<T>(t);
}

logger_wrapper.cpp

#include "logger_wrapper.h"


LoggerWrapper::LoggerWrapper(logging::LoggerInterface *logger, logging::LogPriority priority)
    : logger_{ logger }
    , priority_ { priority }
{

}

bool LoggerWrapper::log_enabled()
{
    return (nullptr != logger_) && (logger_->isLogPriorityEnable(priority_));
}

std::stringstream& LoggerWrapper::get_stream()
{
    return stream_;
}

LoggerWrapper::~LoggerWrapper()
{
    if (log_enabled())
    {
        logger_->log(priority_, stream_.str());
    }
}

代码编译成功,但我有一些 MISRA 警告:

M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<basic_string&>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<basic_string<char,char_traits<char>,allocator<char>>>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<const atomic&>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<const basic_string&>())
M5.17.1 (required): Missing overload for corresponding assignment version of operator (operator<<<const char (&)[10]>())
...

根据 MISRA C++ 2008,规则 M-5-17-1 指出:

The semantic equivalence between a binary operator and its assignment operator form shall be preserved.

我希望有人能向我解释警告的含义以及我应该如何删除它。 非常感谢任何答复。谢谢。

MISRA 指南本质上说“对于任何二元运算符(称之为 @),如果你为你的 class 重载 operator@() 然后也重载 operator@=() ,并确保他们的行为始终如一”。目的是确保(其中 x 是您的 class 的一个实例)。

 x = x @ y;    //  @ may represent +, - , <<, *, /, .....

与(即符合)具有相同的净效果。

x @= y;

在您的情况下,您的 class 具有(模板化的)operator<<() 重载但没有对应的 operator<<=().

重载

停止警告的一种方法是在您提供 operator<<() 时提供相应的 operator<<=() 重载(反之亦然)。

例如,提供一个operator<<=()

template <typename T>
LoggerWrapper& operator<<=(LoggerWrapper& record, T&& t)
{
    if (record.log_enabled())
    {
        record.get_stream() << std::forward<T>(t);
    }
    return record;
}

and(为了确保所需的一致性),使用定义 operator<<() 的方法,因此它调用 operator<<=().

template <typename T>
LoggerWrapper& operator<<(LoggerWrapper& record, T&& t)
{
     return operator<<=(record, t);
}