我如何告诉 clang-tidy 切片特定的 class 是可以的?

How do I tell clang-tidy that slicing a particular class is ok?

我有一个 class Point 从另一个 class 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:[=25 时从未使用过转换函数=]

[class.conv.fct]
A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) 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);

这个clang-tidy slicing flag is based on C++ Core Guidelines and they link to the exact section。在这里,您可以获得指南的推理以及何时切片的替代方案:

Alternative

If you mean to slice, define an explicit operation to do so. This saves readers from confusion.

在您的示例中,您可以这样:

struct Point : public Vec3 {
    int control;
    Vec3 copy_as_vec3() { return Vec3 {x, y, z}; }
};