如何按照 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 {}
};
我的团队正在开发一个嵌入式系统,我们需要遵循 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?
仅关于指针转换的相关问题:
编辑:如前所述,只有 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 {}
};