我如何告诉叮叮当当的整洁切片特定类是可以的?
How do I tell clang-tidy that slicing a particular class is ok?
>我有一个类Point
,它公开继承了另一个类Vec3
并添加了一些数据成员。例如,当向样条询问沿其一定距离的坐标时,返回的额外数据可能是最近控制点的索引。一个要求是,不关心Point
中额外数据的用户应该能够像使用它一样使用它Vec3
。
Point spline(double distance);
Vec3 position = spline(0.4);
从语言规范的角度来看,这符合预期,但我们最近合并了 clang-tidy,它给出了以下警告:
error: slicing object from type 'Point' to 'Vec3' discards 4 bytes of state [cppcoreguidelines-slicing
这是真的,我希望通常启用该检查,但是有没有办法告诉clang-tidy将Point
切成Vec3
是可以的?
我尝试将operator Vec3()
添加到Point
,希望它会选择切片,但显然转换为基类时从未使用转换函数:
[class.conv.fct]
转换函数永远不会用于将(可能符合 cv 的(对象转换为(可能符合 cv 的(相同对象类型(或对它的引用(、该类型的(可能符合 cv 条件的(基类(或对它的引用(或(可能符合 cv 条件的(void
class.conv.fct
强调我的。
一个小例子:
struct Vec3 {
double x, y, z;
};
struct Point : public Vec3 {
int control;
operator Vec3() { return Vec3 {x, y, z}; } // This does nothing.
};
Point spline(double distance)
{
return Point {distance, 0.0, 0.0, 0};
};
int main()
{
Vec3 point = spline(0.1);
}
main.cpp:7:5: error: conversion function converting 'Point' to its base class 'Vec3' will never be used [clang-diagnostic-warning,-warnings-as-errors]
operator Vec3() { return Vec3 {x, y, z}; } // This does nothing.
^
main.cpp:17:18: error: slicing object from type 'Point' to 'Vec3' discards 4 bytes of state [cppcoreguidelines-slicing,-warnings-as-errors]
Vec3 point = spline(0.1);
这个叮叮当当的切片标志基于C++核心指南,它们链接到确切的部分。在这里,您可以获得指南的原因以及何时进行切片的替代方案:
另类
如果要切片,请定义显式操作来执行此操作。这 使读者免于困惑。
在您的示例中,您可以像这样:
struct Point : public Vec3 {
int control;
Vec3 copy_as_vec3() { return Vec3 {x, y, z}; }
};