c ++ пометить значение перечисления как устаревшее? - PullRequest
22 голосов
/ 30 марта 2011

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

например,

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

Вторым призовым решением было бы решение ifdef для MSVC и GCC.

Ответы [ 8 ]

14 голосов
/ 30 марта 2011

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

enum MyEnum {
    firstvalue = 0,
    secondvalue,
    thirdvalue, // deprecated
    fourthvalue
};
#pragma deprecated(thirdvalue)

, тогда, когда бы ни использовалась переменная, компилятор выведет следующее:

warning C4995: 'thirdvalue': name was marked as #pragma deprecated

EDIT
Это выглядит немного странно, и у меня нет компилятора 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

6 голосов
/ 13 октября 2015

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

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

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

3 голосов
/ 30 марта 2011

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

enum MyEnum {
    firstvalue = 0
    secondvalue,
    thirdvalue
};
__attribute__ ((deprecated)) const MyEnum fourthvalue = MyEnum(thirdvalue + 1);
3 голосов
/ 30 марта 2011

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

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 и не требует нарушения безопасности типов. К сожалению, он по-прежнему злоупотребляет вашим кодом с помощью макросов, так что. Но насколько я могу судить, это так хорошо, как только может.

Предложение, сделанное Томом, намного чище (я полагаю, работает для MSVC), но, к несчастью, единственное сообщение, которое gcc даст вам, - "игнорирование прагмы".

1 голос
/ 28 ноября 2013

Вы можете использовать атрибут [[deprecated]] в C ++ 14.

http://www.open -std.org / jtc1 / sc22 / wg21 / docs / paper / 2013 / n3760.html

1 голос
/ 30 марта 2011

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

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

Это не сработает в контексте, когда нужна константа.

1 голос
/ 30 марта 2011

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

0 голосов
/ 30 марта 2011

У меня есть решение (вдохновленное Марком Б), которое использует 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 template, тогда вы можете покончить с зависимостью от Boost.

...