インターフェイスに、移植可能なC ++で非推奨にするメソッドがあります。私がこれについてグーグル検索したとき、私が得たすべてはマイクロソフト固有のソリューションでした。#pragma deprecatedおよび__declspec(deprecated)。
2番目の賞の解決策は、MSVCおよびGCCソリューションのifdefです。
ありがとう
インターフェイスに、移植可能なC ++で非推奨にするメソッドがあります。私がこれについてグーグル検索したとき、私が得たすべてはマイクロソフト固有のソリューションでした。#pragma deprecatedおよび__declspec(deprecated)。
2番目の賞の解決策は、MSVCおよびGCCソリューションのifdefです。
ありがとう
回答:
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)
現在と同じ場所に配置できるため、マクロを簡略化できます。
#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]]
廃止されたマクロをどのように使用しますか?:-)
DEPRECATED void foo(...);
代わりにDEPRECATED(void foo(...));
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)
13.10以降をサポート(Visual Studio 2003)__declspec(deprecated(message))
14.0以降をサポート(Visual Studio 2005)[[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
ヘドレーを使用したくない場合は*_VERSION_CHECK
、*_HAS_ATTRIBUTE
マクロとマクロを削除する方法を理解するための演習として残します(ヘドレーは主に書いたので、定期的に考える必要はありません)。
GLibを使用している場合は、G_DEPRECATED
およびG_DEPRECATED_FOR
マクロを使用できます。これらはHedleyのものほど堅牢ではありませんが、すでにGLibを使用している場合は、追加するものはありません。
Intel Compiler v19.0の場合、これを__INTEL_COMPILER
評価して1900
次のように評価します。
# if defined(__INTEL_COMPILER)
# define DEPRECATED [[deprecated]]
# endif
次の言語レベルで機能します。
インテルコンパイラーには[[deprecated]]
、他のすべてのコンパイラーが行う特定の言語要素の属性をサポートしないというバグがあるようです。例として、GitHubの(非常に優れた){fmtlib / fmt}ライブラリのv6.0.0をインテルコンパイラーv19.0でコンパイルします。壊れます。次に、GitHubコミットの修正を参照してください。