c ++标记枚举值是否已弃用?

时间:2011-03-30 14:57:36

标签: c++ enums deprecated

是否可以将枚举值标记为已弃用?

e.g。

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

二等奖解决方案是ifdef MSVC和GCC解决方案。

8 个答案:

答案 0 :(得分:14)

你可以这样做:

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

然后当使用变量时,编译器将输出以下内容:

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

修改
这看起来有点hacky,我没有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答案的组合

答案 1 :(得分:6)

从GCC 6开始,您可以简单地弃用枚举:

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

来源:https://gcc.gnu.org/gcc-6/changes.html

答案 2 :(得分:3)

好吧,既然我们已经处于宏观黑客行为,这是我的: - )

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,它不要求你打破类型安全。不幸的是它仍然用宏来滥用你的代码,所以嗯。但据我所知,这是最好的。

Tom提出的建议更清晰(我认为适用于MSVC),但不幸的是gcc给你的唯一信息是“忽略了pragma”。

答案 3 :(得分:3)

您可以在枚举声明之外声明枚举常量:

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

答案 4 :(得分:1)

使用编译器相关编译指示:以下是GccVisual Studio的文档。

答案 5 :(得分:1)

您可以使用一些宏hackery。

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

当需要常量时,这不适用于上下文。

答案 6 :(得分:1)

您可以使用C ++ 14中的[[deprecated]]属性。

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

答案 7 :(得分:0)

我有一个解决方案(灵感来自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的依赖。