[英]How to choose function implementation based on C++ version
我已經重新定義了某些C ++函數對象(STL函數),以便為它們提供constexpr operator()。 我需要這些功能來在編譯時進行評估,以用於模板元編程。 C ++ 14為STL功能庫提供了constexpr等效項。 目前,我正在使用C ++ 11編譯代碼,但最終可能會升級到C ++ 14。 如何實現這些功能,以便如果升級到C ++ 14,它將自動從STL中選擇功能對象,而不是我的自定義實現。
到目前為止,這是我的方法:
namespace foo {
template <class T = void>
struct less {
constexpr bool operator()(T const& lhs, T const& rhs) const {
return lhs < rhs;
}
};
}
編輯 :我知道如果我只是用std為我的命名空間加上別名,就可以使用__cplusplus
來完成。 但是,這將是一個糟糕的解決方案,因為我會污染其他所有實例的名稱空間foo。
選項,其方法可能對工作的影響最小,對代碼的影響最小,首先:
使用編譯器的包含文件路徑選擇標題的不同版本。
編譯器版本嗅探和條件編譯(例如#ifdef
)。
批發代碼編輯,可能是自動化的。
編譯器嗅探非常脆弱,但是很常見。
僅檢查__cplusplus
的值通常是不夠的。
例如,使用編譯器的include路徑,您首先定義一個頭文件<relops.hpp>
,它根據C ++ 14功能,默認實現來定義或命名所有內容,並將其放置在常規頭文件頭目錄中。
並通過編譯器的include路徑(例如,對於g ++的CPATH
和對於Visual C ++的INCLUDE
),如果特定的編譯器需要,則將其定向為首先在其他目錄中查找<relops.h>
以獲取系統特定的頭文件。
並且此<relops.h>
會定義事物本身,就像在您提供的代碼中一樣。
隨着條件編譯你反而會確定基於宏如編譯器和版本__cplusplus
, _MSC_VER
, __GNUC__
,一些適用於Mac,可能更多。 您將因此定義一些符號,例如IS_CPP14
。 然后,您將使用#if IS_CPP14
… #else
… #endif
。
您可以使用基於__cplusplus
基於預處理器的解決方案,而不會污染foo
名稱空間,具體如下:
namespace foo {
#if __cplusplus < 201402L
template <class T = void>
struct less {
constexpr bool operator()(T const& lhs, T const& rhs) const {
return lhs < rhs;
}
};
#else
using std::less;
#endif
}
它為14之前的C ++版本定義了foo::less
的自定義版本,並為新的C ++版本創建了std::less
的別名(仍可用作foo::less
)。
(常量201402L
來自標准本身。要求C ++ 14的編譯器將__cplusplus
至少設置__cplusplus
值)。
在編譯器僅部分支持C ++ 14的情況下,即使該部分支持包括constexpr
限定的std::less::operator()
,上述代碼也可能導致您less
使用自定義實現。 顯然,這對於Visual Studio的最新版本是正確的。 我建議這甚至不值得擔心; 無論如何,都應該內聯對該函數的調用,並且當您使用適當兼容的C ++ 14編譯器進行編譯時,您將獲得所需的確切(編譯級)行為。 或者,您可以擴展預處理器邏輯(即檢查編譯器特定的宏),以識別已知具有足夠一致性的特定編譯器版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.