我怎样才能弃用C++标头

  • 本文关键字:C++ 标头 c++ deprecated
  • 更新时间 :
  • 英文 :


我想弃用C++头,这样,如果有人在代码中包含它,编译器就会发出警告。

我知道我可以弃用单个符号,例如,使用C++14[[deprecated]],但对于标头有类似的东西吗?也许是什么聪明的把戏?

请注意,即使用户没有使用头中的任何内容,我也希望编译器发出警告。

这里有一个可能的(尽管可能不太优雅(解决方案。

在标题中插入类似的代码

// badheader.hpp
namespace {
[[deprecated("This header is deprecated")]]
constexpr static int badheader_hpp_is_deprecated = 0;
constexpr static int please_dont_use_badheader_hpp = badheader_hpp_is_deprecated;
}

这将创建一个不推荐使用的变量badheader_hpp_is_deprecatedplease_dont_use_badheader_hpp的初始化会触发不推荐使用的警告。请注意,我将两个变量都放在一个匿名命名空间中,以避免可能的名称冲突。尽管如此,正如注释中所指出的,如果在同一编译单元中,在匿名命名空间内声明了具有相同名称的变量,则仍可能发生名称冲突。因此,正如评论中所建议的那样,上面代码中的变量有一个描述性的名称,这使得名称冲突变得极不可能。

一个非标准但相当便携的解决方案:

#pragma message("Header `foo.h` is deprecated!")

GCC、Clang和MSVC都接受这一点。GCC和Clang也接受没有( )的表格。

这不一定是";"警告";,但应该足够好。

我建议用一个同名的命名空间包围你的命名空间,并从封闭的命名空间中using它。

#pragma once
namespace your_namespace {
namespace [[deprecated]] your_namespace {
// old stuff
}
using namespace your_namespace;
}

这不应该用your_namespace中的任何内容污染全局命名空间,并且如果包含标头,仍然会发出警告。旧的东西仍然可以像以前一样通过your_namespace::访问。

由于这是一个破坏ABI的更改,如果您在弃用标头时还没有,我建议您也使用库的主要版本。

这是从range-v3库中无耻地复制的:

#ifdef __GNUC__
#define RANGES_PRAGMA(X) _Pragma(#X)
#define RANGES_DEPRECATED_HEADER(MSG) RANGES_PRAGMA(GCC warning MSG)
#elif defined(_MSC_VER)
#define RANGES_STRINGIZE_(MSG) #MSG
#define RANGES_STRINGIZE(MSG) RANGES_STRINGIZE_(MSG)
#define RANGES_DEPRECATED_HEADER(MSG) 
__pragma(message(__FILE__ "(" RANGES_STRINGIZE(__LINE__) ") : Warning: " MSG))
#endif
RANGES_DEPRECATED_HEADER("Yikes! A deprecated header!")

请使用编译器资源管理器进行尝试。

如果你的头有一个名称空间,我想你可以在上面使用[[deprecated]]吗?但这在匿名命名空间上不起作用。用户必须使用来自顶部空间的东西才能工作。

如果您可以将头放在命名空间中,那么您所要做的就是生成一个using语句,该语句将触发警告。这也是一个很好的主意,可以隔离这些功能,并确保用户在使用它们时会有更多的困难,如果这是一个目标的话。

namespace [[deprecated]] N {
struct S {
};
}
using N::S;

但是,如果您负担不起名称空间,根据元素的数量,您可能不想在所有元素上使用using。也许这可能是合法拥有using namespace N;的情况,但我不确定。

经过一些研究,你可以使用#pragma message "Message"来实现你想要的目标。看到这个答案

导螺杆

相关内容

  • 没有找到相关文章

最新更新