我如何告诉叮叮当当的整洁切片特定类是可以的?

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

本文关键字:切片 何告诉 叮叮当当      更新时间:2023-10-16

>我有一个类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}; }
};