Я пытаюсь найти хороший способ удалить устаревшие классы из моей библиотеки, сохраняя при этом хорошие сообщения об ошибках. Эта идея основана на чем-то я уже делать с функциями:Как удалить классы при сохранении предупреждений об отставке
namespace
{
[[deprecated("This function has been replaced by combust()")]]
void explode() = delete; // Using variadic templates in reality to have all signatures covered
void combust() {}
}
int main()
{
explode();
combust();
}
В лязгом, это дает мне хорошее сообщение об ошибке:
<source>:11:2: error: call to deleted function 'explode': This function has been replaced by combust()
explode();
^~~~~~~
НКУ только дает мне только сообщение, что эта функция была удалена , Хотя, это все еще показывает намерение для всех, кто пытается обновить библиотеку, которая игнорирует предупреждение об устаревании.
Итак, поскольку это библиотека C++, у меня в основном есть классы, и я ищу правильный способ сделать что-то подобное с этими классами. Мой текущий подход выглядит следующим образом:
namespace
{
class [[deprecated("Class has been replaced by Bar")]] Foo
{
Foo() = delete; // And every other method I had in this class
};
class Bar
{
};
}
int main()
{
Foo f;
Bar b;
}
В основном это дает мне следующие предупреждения/ошибки в звоне (и аналогичном в НКУ):
<source>:13:5: warning: 'Foo' is deprecated: Class has been replaced by Bar [-Wdeprecated-declarations]
Foo f;
^
<source>:3:60: note: 'Foo' has been explicitly marked deprecated here
class [[deprecated("Class has been replaced by Bar")]] Foo
^
<source>:13:9: error: call to deleted constructor of '(anonymous namespace)::Foo'
Foo f;
^
<source>:5:8: note: 'Foo' has been explicitly marked deleted here
Foo() = delete;
^
Где я могу жить с этим бесполезным кодом для функций, как это однострочные, это становится громоздким для классов, поскольку у них может быть много методов.
Итак, что я ищу, это хороший способ сделать следующее: (без компиляции кода)
class [[deprecated("Class has been replaced by Bar")]] Foo = delete;
Замкнутый я попал в Oneliner является:
struct [[deprecated("Class has been replaced by Bar")]] Foo { Foo() = delete; };
struct [[deprecated("Class has been replaced by Bar")]] Foo;
Обратите внимание, что не распространяется на случаи, когда Foo передается по ссылке, и вызываются некоторые методы.
Есть ли у кого-нибудь лучшее решение для удаления классов при наличии явных предупреждений об устаревании для некоторых из следующих выпусков?
Я думаю, вы используете неправильные термины. «Устаревший» должен * никогда * означать «нефункциональный». [[устарело]] следует применять только к методам и классам *, которые работают *. Устаревание - это признак того, что, пока это работает * прямо сейчас *, он может быть удален * позже. Вы никогда не должны удалять функции/классы, а затем маркировать их [[устарело]]. Просто удалите их; компилятор позволит пользователям классов/функций знать, что они скоро ушли;) –
@NicolBolas Как объяснялось, это второй шаг, облегчающий миграцию для тех, кто игнорирует предупреждения об устаревании. И для функций люди из Clang считают его хорошей идеей, поскольку у них даже есть конкретное сообщение об ошибке, чтобы объединить эти два. – JVApen
"и некоторые методы называются" - как методы называются 'class Foo {Foo() = delete; } 'точно? – Yakk