Разрешить задавать атрибут [[deprecated]] для функций-членов класса вне его объявления

Алексей Телишев
Алексей Телишев

Хотелось бы помечать некоторые функции классов из стронних библиотек (например, Qt) помечать как [[deprecated]] для того, чтобы их нельзя было использовать. Для обычных функций это работает  - нужно заново сделать декларацию функции, пометив ее как [[deprecated]]. Для функций-членов класса это не работает - вне класса можно писать только определение функции, а декларацию нельзя. В идеале было бы, если бы работал следующий синтаксис:

struct X
{
  double f (double x);
};

[[deprecated]] double X::f (double);

Интересно, что в gcc такой синтаксис почти работает - он выдает предупреждение для каждого вызова такой функции, но при этом сначала выдаст ошибку "declaration of '...' outside of class is not definition"

-2
рейтинг
3 комментария
Никита Колотов

С одной стороны, такой возможности действительно иногда явственно нехватает. Но если уж идти в этом направлении, то не ограничиваться полумерами, и добавлять сразу возможность помечать как [[deprecated]] также и внутрение типы, и поля классов и все прочее, что им можно помечать сейчас.

С другой стороны, это уже достаточно большие изменения. Например, как оно может выглядеть в случае типа? По аналогии наверное как-то так:

struct foo
{
    using bar = int;
};

[[deprecated]] foo::bar;

Но сейчас foo::bar; является невалидной конструкций и вообще это похоже скорее на недописанное объявление глобальной переменной. В случае какого-нибудь шаблона или заданного значения енумератора видимо будут не меньшие сложности. Также наверное придется добавлять какие-то дополнительные правила для доступа к private и protected членам в таких конструкциях. А язык и так уже усложнен сверх всякой меры.

Также практика показывает, что дублировать какие-то декларации из сторонних библиотек корректируя их интерфейс - дело неблагодарное и вместо этого проще и надежнее делать обертки.

Никита Колотов
Обновлено 
Sergey Semushin

Никита Колотов, а на мой взгляд полумеры то, что есть сейчас. Ибо досчить того, чтоб "A name declared non-deprecated may be redeclared deprecated." сработало можно примерно в половине случаев (свободные функции, глобальные переменные, неймспейсы, тайпдефы путём их повторения). Отсутствием полумер будет возможность эту фичу вообще запретить.

Для повторной декларации классов/енумов однако разрешить [[deprecated]] наверно чуть проще, чем для членов класса ибо это не требует отдельных конструкций языка, а просто специальной лазейки для [[deprecated]] поскольку сейчас любые аттрибуты у класса компиляторы дают писать только у определения.

Sergey Semushin
Никита Колотов

Sergey Semushin, то, что есть сейчас, я бы охарактеризовал как стихийно сложившийся порядок, при котором может имется несколько отличающихся объявлений, дополняющих друг друга. Сомнительный, надо сказать, порядок.

Вообще-то сейчас [[deprecated]] для классов можно указывать при объявлении. т.е. пометить класс из внешней библиотеки как [[deprecated]] можно примерно так

// foo_deprecation.hpp
class [[deprecated]] foo;

// foo.hpp
class foo{};

// main.cpp
#include "foo_deprecation.hpp"
#include <foo.hpp>

int main()
{
    foo f{}; // warning: 'foo' is deprecated
}

А вот навешивать атрибуты уже после определения класса - это да, нельзя.

Никита Колотов
Обновлено 
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения