Можно ли пометить значение перечисления как устаревшее?
например.
enum MyEnum {
firstvalue = 0
secondvalue,
thirdvalue, // deprecated
fourthvalue
};
Второе призное решение будет состоять в том, чтобы: ifdef MSVC и GCC-решение.
Можно ли пометить значение перечисления как устаревшее?
например.
enum MyEnum {
firstvalue = 0
secondvalue,
thirdvalue, // deprecated
fourthvalue
};
Второе призное решение будет состоять в том, чтобы: ifdef MSVC и GCC-решение.
вы можете сделать это:
enum MyEnum {
firstvalue = 0,
secondvalue,
thirdvalue, // deprecated
fourthvalue
};
#pragma deprecated(thirdvalue)
тогда, когда используется переменная, компилятор выводит следующее:
warning C4995: 'thirdvalue': name was marked as #pragma deprecated
ИЗМЕНИТЬ
Это выглядит немного взломанным, и у меня нет компилятора GCC для подтверждения (может кто-то это сделал для меня?), но он должен работать:
enum MyEnum {
firstvalue = 0,
secondvalue,
#ifdef _MSC_VER
thirdvalue,
#endif
fourthvalue = secondvalue + 2
};
#ifdef __GNUC__
__attribute__ ((deprecated)) const MyEnum thirdvalue = MyEnum(secondvalue + 1);
#elif defined _MSC_VER
#pragma deprecated(thirdvalue)
#endif
это комбинация моего ответа и ответа MSalters
Хорошо, так как мы уже находимся в макро-хаках, вот моя: -)
enum MyEnum
{
foo,
bar,
baz
};
typedef __attribute__ ((deprecated))MyEnum MyEnum_deprecated;
#define bar ((MyEnum_deprecated) bar)
int main ()
{
int a = foo; // yuck, why did C++ ever allow that...
int b = bar;
MyEnum c = foo;
MyEnum d = bar;
return 0;
}
Это работает с gcc, и это не требует нарушения безопасности типа. К несчастью, он все еще злоупотребляет вашим кодом макросами, поэтому meh. Но, насколько я мог понять, он так же хорош, как и он.
Предложение, сделанное Томом, намного чище (работает для MSVC, я полагаю), но к несчастью, единственное сообщение, которое gcc даст вам, это "игнорирование прагмы".
Вы можете объявить константы перечисления вне объявления перечисления:
enum MyEnum {
firstvalue = 0
secondvalue,
thirdvalue
};
__attribute__ ((deprecated)) const MyEnum fourthvalue = MyEnum(thirdvalue + 1);
Начиная с GCC 6 вы можете просто отказаться от перечислений:
enum {
newval,
oldval __attribute__ ((deprecated ("too old")))
};
Источник: https://gcc.gnu.org/gcc-6/changes.html
Использование зависимых от компилятора pragmas: Вот документация для Gcc и Visual Studio.
Возможно, вы сможете использовать некоторые макро-хаки.
enum MyEnum {
firstvalue = 0
secondvalue,
real_thirdvalue, // deprecated
fourthvalue
};
template <MyEnum v>
struct real_value
{
static MyEnum value()
{
1 != 2U; // Cause a warning in for example g++. Leave a comment behind for the user to translate this warning into "thirdvalue is deprecated"
return v;
}
};
#define thirdvalue (real_value<real_thirdvalue>::value());
Это не будет работать в контексте, когда необходима константа.
Вы можете использовать атрибут [[устаревший]] из С++ 14.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3760.html
У меня есть решение (вдохновленное Mark B's), которое использует boost/serialization/static_warning.hpp. Однако моя позволяет использовать thirdvalue
как символическую константу. Он также создает предупреждения для каждого места, где кто-то пытается использовать thirdvalue
.
#include <boost/serialization/static_warning.hpp>
enum MyEnum {
firstvalue = 0,
secondvalue,
deprecated_thirdvalue, // deprecated
fourthvalue
};
template <int line>
struct Deprecated
{
BOOST_SERIALIZATION_BSW(false, line);
enum {MyEnum_thirdvalue = deprecated_thirdvalue};
};
#define thirdvalue (static_cast<MyEnum>(Deprecated<__LINE__>::MyEnum_thirdvalue))
enum {symbolic_constant = thirdvalue};
int main()
{
MyEnum e = thirdvalue;
}
В GCC я получаю предупреждения, которые в конечном итоге указывают на линии преступника, содержащие thirdvalue
.
Обратите внимание, что использование шаблона Deprecated
делает его так, что строка вывода компилятора "созданная здесь" показывает, где используется устаревшее перечисление.
Если вы можете выяснить способ создания сгенерированного предупреждения внутри шаблона Deprecated
, то вы можете покончить с зависимостью от Boost.