c++ 初始化不推荐使用的字段而不触发警告

z0qdvdin  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(79)

我有一个结构体,其中有一个静态字段,我想弃用。但是,现在我仍然想初始化它。下面的代码段在MSVC和愚者(但不是Clang)下产生一个警告:

struct A {
    ~A();
};

struct B {
    [[deprecated]] static A X;
};

A B::X; //warning C4996: 'B::X': was declared deprecated

有趣的是,如果我删除~A();,警告就会消失。
有没有办法初始化B::X而不产生警告,而不求助于hacky pragma之类的东西?

kyvafyod

kyvafyod1#

删除析构函数后,警告就会消失,因为A可以被轻易地析构(也可以被构造),这意味着编译器不需要发出实际的代码来初始化任何东西,因此不会生成引用B::X的代码。因此,没有触发器发出警告。
这也暗示了一种可能的解决方法:使B::X成为“平凡的”东西,例如引用。例如(live on godbolt):

struct A {
    ~A();
};

struct B {
  static A helper;
  [[deprecated]] static A & X;
};

A B::helper;
A & B::X = B::helper;

这不会产生警告,只会在实际使用它的地方产生警告。而且在大多数情况下,这种变通方法不会改变程序的语义。
顺便说一下,静态成员是按照其定义的顺序初始化的,例如,请参见this answer

相关问题