如何按照 MISRA C++ 实现 CRTP

How to implement the CRTP following MISRA C++

我的团队正在开发一个嵌入式系统,我们需要遵循 MISRA C++。

我们正在重构代码以使用更少的虚拟方法,因此我们正在尝试实现 CRTP 以使用静态多态而不是动态多态。

但是我们有静态多态性需要指针转换的问题,所以我们的静态分析检查器抱怨。

这是界面

template <typename T>
class UpdateMethod
{
protected:
    ~UpdateMethod() {}
 public:
    void operator()() const
    {
        // [MISRA Rule 5-2-7] violation:
        static_cast<const T*>(this)->update();
    }
};

这是其中一种实现方式:

class A
    : public UpdateMethod<A>
{
 public:
    void update() const {}
};

当通过 MISRA 检查程序时,它抱怨 static_cast(从 ptr 到 ptr (e926) 的转换。

所以,我的问题是:有没有什么好的方法可以在不抑制 MISRA 警告的情况下以安全的方式实施 CRTP?

仅关于指针转换的相关问题: 我在CRTP中有同样的错误。

编辑:如前所述,只有 C++03,没有像 boost 这样的外部库。

好的问题是该工具会检查模板定义而不是模板实例化。

必须有一些方法来帮助工具了解情况。最好的方法是 C++2a 概念,但很可能工具不支持,编译器可能也不支持。

其他解决方案将提供 static_assert 希望该工具能够理解:

template <typename T>
class UpdateMethod
{
    static_assert(std::is_base_of<UpdateMethod<T>, T>::value, "This is CRTP");
protected:
    ~UpdateMethod() {}
 public:
    void operator()() const
    {
        static_cast<const T*>(this)->update();
    }
};

另一种方法是使用 SFINAE 并在施放 make seance 时使运算符可用:

template <typename T>
class UpdateMethod
{
protected:
    ~UpdateMethod() {}
public:

    typename std::enable_if<std::is_base_of<UpdateMethod<T>, T>::value>::type
    operator()() const
    {
        static_cast<const T*>(this)->update();
    }
};

或者两者都用。

试试这个我希望工具能理解并停止报告错误。如果不是,那么恕我直言,这是工具中的错误。

有人指出必须使用C++03。在这种情况下,您可以使用 boost,其中此助手模板 enable_if and is_base_of 最初定义的地方。

您可以使用相反的方法:

template <typename T>
class UpdateMethod : public T
{
 public:
    void operator()() const
    {
        this->update();
    }
};

class A_impl
{
 public:
    void update() const {}
};

typedef UpdateMethod<A_impl> A;

检查员不喜欢的是沮丧。我们可以完全不用铸造吗?派生的 class 可以提供具有正确类型的正确值,例如在施工期间。有点沮丧。这将花费您一个额外的存储指针。像这样:

template <typename T>
class UpdateMethod
{
protected:
    T* implThis;
    ~UpdateMethod() {}
    UpdateMethod(T* implThis):implThis(implThis) {}
 public:
    void operator()() const
    {
        // this was the problematic cast
        implThis->update();
    }
};

class A
    : public UpdateMethod<A>
{
 public:
    A(): UpdateMethod(this) {}
    void update() const {}
};