有沒有一種規範的方法來處理嘗試在TR1和非TR1工具鏈之間維護便攜式代碼時出現的命名空間問題?C++如何處理可移植代碼中的tr1和非tr1命名空間?
我有一個VC++ 2010項目,#include <type_traits>
。我也有一個LLVM 3.0編譯器,可以處理這個問題。這允許我使用的模板,例如:
std::enable_if<typename>
std::is_enum<typename>
但是我還需要在一個Xcode 4.5鐺編譯器構建並維護這些代碼:
$ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version
Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.2
Thread model: posix
這個編譯器似乎並未有包括文件,而是它有一個。然而,這引起了我的問題,因爲命名空間已經從性病::改爲__gnu_cxx ::,這意味着我必須使用:
__gnu_cxx::__enable_if<typename>
不知怎的,我能夠確定的是,符號__GLIBCXX__
的定義是足以確定我是否應該使用其中一種(甚至不知道這是否正確,但現在它可以在我使用的編譯器之間使用)。
所以,我可以訴諸使用預處理宏:
#ifdef __GLIBCXX__
# include <tr1/type_traits>
# define ENABLE_IF __gnu_cxx::__enable_if
#else
# include <type_traits>
# define ENABLE_IF std::enable_if
#endif
但這似乎像它可能更多的是黑客不是一個妥善的解決辦法。 (其實我想這一點,這是行不通的,因爲試圖用__gnu_cxx::__enable_if
導致此錯誤:
error: too few template arguments for class template '__enable_if'
- 進一步挖掘表明,這種版本enable_if實際上有兩個模板參數,我現在很失落。 ...)
我想過做喜歡的事:
#ifdef __GLIBCXX__
# include <tr1/type_traits>
namespace __gnu_cxx = foo;
#else
# include <type_traits>
namespace std = foo;
#endif
... foo::enable_if<...>
然而,這並不工作,因爲模板被稱爲enable_if
在一個命名空間中,但在另一箇中爲__enable_if
。
我敢肯定,我不是第一個處理這個問題的人 - 有人能指出我在解決此問題的行業最佳做法嗎?或者我應該只使用Boost來代替?
還有一個類似的問題(我認爲),但只有部分回答here。有更好的選擇嗎?
編輯:我想這一點,與<boost/type_traits.hpp>
:
#include <boost/type_traits.hpp>
template <typename ValueType>
class Extractor <ValueType, typename boost::enable_if<boost::is_enum<ValueType>::value>::type> {
public:
ValueType extract(double value) {
return static_cast<ValueType>(static_cast<int>(value)); // cast to int first, then enum, to satisfy VC++2010
}
};
enum MyEnum { Enum0, Enum1 };
Extractor<MyEnum> e;
MyEnum ev = e.extract(1.0);
但是這給了我在Xcode 4.5以下編譯器錯誤:
error: expected a qualified name after 'typename'
class Extractor <ValueType, typename boost::enable_if<boost::is_enum<ValueType>::value>::type> {
^
error: unknown type name 'type'
因此,它似乎並不認爲性病:: enable_if和boost :: enable_if是插件兼容的。
這個問題是一個後續從http://stackoverflow.com/questions/14821846 – meowsqueak 2013-02-12 01:21:15
得到了一些與boost/type_traits.hpp工作 - 但請注意,需要使用boost :: enable_if_c作爲一個直接替換對於std :: enable_if - 或者顯然可以刪除尾部::值 - 請參閱「更多信息」,第2部分,http://www.gockelhut.com/c++/articles/has_member – meowsqueak 2013-02-12 01:36:32
不幸的是,它在這裏擺動 - n-roundabouts - boost/type_traits.hpp包含is_complex.hpp,其中包括 - 不幸在此特定(精簡)編譯環境中不存在。嘎。通過包含和而不是來解決這個問題 - 很高興Boost創建者將所有東西都分割得如此有用 - 方便。 –
meowsqueak
2013-02-12 01:39:55