我在接口中有一个方法,我想用便携式C ++弃用。 当我用Google搜索时,我得到的是微软特定的解决方案; #pragma deprecated和__declspec(deprecated)。
二等奖解决方案是ifdef MSVC和GCC解决方案 感谢
答案 0 :(得分:164)
在C ++ 14中,您可以使用[[deprecated]]
属性将函数标记为已弃用(请参见第7.6.5节[dcl.attr.deprecated])。
attribute-token
deprecated
可用于标记仍然允许使用的名称和实体,但由于某种原因不鼓励。
例如,不推荐使用以下函数foo
:
[[deprecated]]
void foo(int);
可以提供描述不推荐使用名称或实体的原因的消息:
[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);
消息必须是字符串文字。
有关详细信息,请参阅“Marking as deprecated in C++14”。
答案 1 :(得分:122)
这应该可以解决问题:
#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>
因为这将被preprocesor解释为将2个参数传递给DEPRECATED宏。在这种情况下,您必须键入dede返回类型。
编辑:更简单(但可能不太广泛兼容)版本here。
答案 2 :(得分:50)
以下是我2008 answer的简化版:
#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);
另见:
答案 3 :(得分:21)
在GCC中,您可以使用不推荐使用的属性声明您的函数:
void myfunc() __attribute__ ((deprecated));
当在.c文件中使用该函数时,这将触发编译时警告。
您可以在“诊断实用程序”下找到更多信息 http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html
答案 4 :(得分:4)
处理便携式项目时,您在某些时候需要为一系列平台提供一部分预处理替代方案,这几乎是不可避免的。 #ifdef这个#ifdef等等。
在这样的部分中,您可以有条件地定义一种弃用符号的方法。我的偏好通常是定义一个“警告”宏,因为大多数工具链都支持自定义编译器警告。然后,您可以继续使用特定的警告宏进行弃用等。 对于支持专用弃用方法的平台,您可以使用它而不是警告。
答案 5 :(得分:3)
以下是2018年的更完整答案。
现在,许多工具不仅可以将某些内容标记为已弃用,还可以提供消息。这允许您告诉人们什么时候被弃用,并且可能将它们指向替代品。
编译器支持仍有很多种:
[[deprecated]]
/ [[deprecated(message)]]
。__attribute__((deprecated))
__attribute__((deprecated))
和__attribute__((deprecated(message)))
支持:
__GNUC__
/ __GNUC_MINOR__
/ __GNUC_PATCHLEVEL__
)__GNUC__
/ __GNUC_MINOR__
,他们只是将其设置为安装的任何GCC版本)__declspec(deprecated)
__declspec(deprecated(message))
您还可以基于[[gnu::deprecated]]
在C ++ 11的最近版本的clang中使用__has_cpp_attribute(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,那就无需添加任何内容了。
答案 6 :(得分:1)
对于Intel Compiler v19.0,将其用作limits
的值为__INTEL_COMPILER
:
1900
适用于以下语言级别:
Intel编译器出现了一个错误,即它不支持所有其他编译器都支持的某些语言元素上的# if defined(__INTEL_COMPILER)
# define DEPRECATED [[deprecated]]
# endif
属性。例如,使用Intel Compiler v19.0在GitHub上编译{fmtlib/fmt}库(非常出色)fix in the GitHub commit的v6.0.0。会破裂的。然后查看How to extract certain length of numbers from a string in python?。