Подтвердить что ты не робот

Значение переменной пересылки С++ как устаревшее?

Можно ли пометить значение перечисления как устаревшее?

например.

enum MyEnum {
    firstvalue = 0
    secondvalue,
    thirdvalue, // deprecated
    fourthvalue
};

Второе призное решение будет состоять в том, чтобы: ifdef MSVC и GCC-решение.

4b9b3361

Ответ 1

вы можете сделать это:

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

Ответ 2

Хорошо, так как мы уже находимся в макро-хаках, вот моя: -)

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 даст вам, это "игнорирование прагмы".

Ответ 3

Вы можете объявить константы перечисления вне объявления перечисления:

enum MyEnum {
    firstvalue = 0
    secondvalue,
    thirdvalue
};
__attribute__ ((deprecated)) const MyEnum fourthvalue = MyEnum(thirdvalue + 1);

Ответ 4

Начиная с GCC 6 вы можете просто отказаться от перечислений:

enum {
  newval,
  oldval __attribute__ ((deprecated ("too old")))
};

Источник: https://gcc.gnu.org/gcc-6/changes.html

Ответ 5

Использование зависимых от компилятора pragmas: Вот документация для Gcc и Visual Studio.

Ответ 6

Возможно, вы сможете использовать некоторые макро-хаки.

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());

Это не будет работать в контексте, когда необходима константа.

Ответ 8

У меня есть решение (вдохновленное 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.