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

标签 c++ templates operator-overloading misra

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

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 指南本质上是说“对于任何二元运算符(称为 @ ),如果您为类重载 operator@() ,那么也重载 operator@=() ,并确保它们的行为一致”。目的是确保(其中 x 是您的类的实例)。

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

具有与以下相同的净效果(即一致)。

x @= y;

就您而言,您的类具有(模板化)重载 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;
}

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

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

关于c++ - 覆盖按位运算符时的 MISRA 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70496043/

相关文章:

c++ - 有什么合理的理由使一元运算符 & 过载?

c++ - pragma keylist 关键字有什么作用?

c++ - 编译时 Ubuntu 12.04 LTS 上的库链接错误

c++ - 在模板类中重载 operator=

c++ - 在左值和右值情况下重载下标运算符 "[ ]"

oop - MATLAB 是否支持 "callable"(即类函数)类?

c++ - 消息循环如何使用线程?

C++ 三字母语言名称到 LCID

c++ - 如何在 C++ 中将字符串转换为模板化类型

c++ - 模板化运算符[] ...可能吗?有用?