我有一个在C++接口中的方法,我想弃用它,并编写便携式代码。
当我在Google上搜索时,我得到了一个仅适用于Microsoft的解决方案:#pragma deprecated
和 __declspec(deprecated)
。
如果没有通用或完全可移植的弃用解决方案,我将接受一个可用于多个特定编译器(如MSVC和GCC)的“第二奖励解决方案”。
我有一个在C++接口中的方法,我想弃用它,并编写便携式代码。
当我在Google上搜索时,我得到了一个仅适用于Microsoft的解决方案:#pragma deprecated
和 __declspec(deprecated)
。
如果没有通用或完全可移植的弃用解决方案,我将接受一个可用于多个特定编译器(如MSVC和GCC)的“第二奖励解决方案”。
在 C++14 中,你可以使用 [[deprecated]]
属性(参见第 7.6.5 节 [dcl.attr.deprecated])标记一个函数为已弃用。
deprecated
属性标记的名字和实体仍然被允许使用,但因某种原因而不推荐使用。
例如,下面的函数 foo
已经被弃用:
[[deprecated]]
void foo(int);
可以提供一个描述名称或实体为何被弃用的消息:
[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);
该消息必须是字符串字面值。
更多细节请参见“在C++14中标记为已弃用”。
#ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func
#endif
...
//don't use me any more
DEPRECATED(void OldFunc(int a, float b));
//use me instead
void NewFunc(int a, double b);
std::pair<int, int>
,则会遇到问题,因为这将被预处理器解释为向DEPRECATED宏传递2个参数。在这种情况下,您需要使用typedef重新定义返回类型。__declspec(deprecated)
放置在相同的位置,因此宏可以简化。 - bames53#define DEPRECATED __declspec(deprecated)
并使用DEPRECATED void MyApi()
。 - DarkWanderer这里是我2008年回答的简化版:
#if defined(__GNUC__) || defined(__clang__)
#define DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED __declspec(deprecated)
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED
#endif
//...
//don't use me any more
DEPRECATED void OldFunc(int a, float b);
//use me instead
void NewFunc(int a, double b);
参见:
[[deprecate]]
为英文单词,表示“废弃”或“弃用”。在翻译过程中,我保留了原句中的符号和表情,并将“macro”翻译为“宏”,使得整个句子更加通俗易懂。) - graham.reedsDEPRECATED void foo(...);
而不是DEPRECATED(void foo(...));
。 - dshepherdvoid myfunc() __attribute__ ((deprecated));
在 .c 文件中使用该函数时,这将触发编译时警告。
更多信息可以在“诊断编译指令”下找到。
以下是2018年更全面的答案。
现在,许多工具不仅允许您将某些内容标记为已弃用,而且还提供了消息功能。这使您能够告诉人们何时出现过期的内容,并可能指向替代方案。
编译器支持仍有很大差异:
[[deprecated]]
/[[deprecated(message)]]
。__attribute__((deprecated))
由GCC 4.0+和ARM 4.1+支持。__attribute__((deprecated))
和__attribute__((deprecated(message)))
适用于:
__GNUC__
/__GNUC_MINOR__
/__GNUC_PATCHLEVEL__
)的编译器__GNUC__
/__GNUC_MINOR__
,它们仅将其设置为安装的GCC版本)__declspec(deprecated)
。__declspec(deprecated(message))
。在基于__has_cpp_attribute(gnu::deprecated)
的C++11最新版本的clang中,您还可以使用[[gnu::deprecated]]
。
我在Hedley中有一些宏,可自动处理所有这些内容,并在新版本中保持最新状态,但当前版本(v2)如下:
#if defined(__cplusplus) && (__cplusplus >= 201402L)
# define HEDLEY_DEPRECATED(since) [[deprecated("Since " #since)]]
# define HEDLEY_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
#elif \
HEDLEY_GCC_HAS_EXTENSION(attribute_deprecated_with_message,4,5,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_ARM_VERSION_CHECK(5,6,0)
# define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
# define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
#elif \
HEDLEY_GCC_HAS_ATTRIBUTE(deprcated,4,0,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0)
# define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
# define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
#elif HEDLEY_MSVC_VERSION_CHECK(14,0,0)
# define HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
# define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
# define HEDLEY_DEPRECATED(since) _declspec(deprecated)
# define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
#else
# define HEDLEY_DEPRECATED(since)
# define HEDLEY_DEPRECATED_FOR(since, replacement)
#endif
如果您不想使用Hedley,而想要摆脱*_VERSION_CHECK
和*_HAS_ATTRIBUTE
宏,那么将其除去的方法留作练习(我写了Hedley主要是因为我不想经常考虑这个)。
如果您使用GLib,则可以使用G_DEPRECATED
和G_DEPRECATED_FOR
宏。虽然它们没有Hedley的宏那么强大,但如果您已经在使用GLib,则无需添加其他内容。
__INTEL_COMPILER
的值为1900
:# if defined(__INTEL_COMPILER)
# define DEPRECATED [[deprecated]]
# endif
[[deprecated]]
属性。例如,在GitHub上使用Intel Compiler v19.0编译remarkly superb {fmtlib/fmt}库的v6.0.0版本时,它会出错。然后查看GitHub提交中的修复。__attribute__((deprecated))
可以在C和C++中使用,至少从ICC 13.0开始,可能更早(Intel倾向于不记录此类信息,因此我不能确定)。 - nemequ
GRIKIFY
标记为已弃用?#define GRIKIFY(x) if (x) Grike(x)
- Eljay