如何在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(。
所以,我的问题是:有没有好的方法来实现CRTP,而不必以安全的方式抑制MISRA警告?
仅与指针转换相关的问题: MISRA C++ 2008 违反规则 5-2-7:不得直接或间接将指针类型的对象转换为不相关的指针类型 我在 CRTP 中也有同样的错误。
编辑:如前所述,只有C++03,没有像boost这样的外部库。
您可以使用相反的方法:
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;
好的问题是该工具检查模板定义而不是模板实例化。
必须有某种方法可以帮助工具了解情况。最好的方法是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 并在铸造降神会时让操作员可用:
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,is_base_of最初定义的位置。
检查器不喜欢的是向下投射。我们可以完全不选角吗?派生类可以使用正确的类型提供正确的值,例如在构造期间。有点预落。它将花费您一个额外的存储指针。喜欢这个:
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 {}
};
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 在类定义之后定义一个私有方法
- 在循环C++中指定字符串之后,不会打印该字符串
- C++宏忽略之后的内容
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- strncpy之后的char数组的错误行为
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- 计算十进制 c++ 之后的数字
- CRTP 单一实例不完整类型或非文本类型
- "x += x--"之后的 x 是什么?
- 类的前向声明之后的类成员函数定义,在类声明之前
- 为什么将双精度转换为 int 似乎在第 16 位数字之后将其四舍五入?
- execlp() 在 fork() 之后无法正常工作
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 我认为我的代码很好,但它在 cin a 之后停止并且没有进一步?
- 将具有固定签名的自定义函数名称注入 CRTP
- 如何在MISRA C++之后实施CRTP
- 检测使用 CRTP 的类中的成员函数
- 简化使用 CRTP 模式的类的声明
- C++ CRTP initialization