Как мне сказать Clang-Tidy, что нарезка определенного класса в порядке? - PullRequest
2 голосов
/ 22 января 2020

У меня есть класс 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);

1 Ответ

2 голосов
/ 22 января 2020

Этот флаг нарезки clang-tidy основан на C ++ Core Guidelines, и они ссылаются на точный раздел . Здесь вы получите обоснование для руководства, а также альтернативу для того, когда нарезка предназначена:

Альтернатива

Если вы хотите нарезать ломтиком, определите явную операцию для этого. Это избавляет читателей от путаницы.

В вашем примере вы могли бы что-то вроде этого:

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