2010-12-22 61 views
0

我目前正在編寫一個C++庫,它將用於GCC for linux和Sun CC for Solaris的編譯。爲了提高性能,我創建了一些基於編譯器選擇不同頭文件的類; GCC使用C++ 0x或TR1或使用niether和Sun CC RogueWave或STLPort。我sturggling制定的#ifdef'ing的類型定義的最佳手段,例如:基於宏的C++頭文件選擇

namespace project { 

    #if defined(__GNUG__) 
     #if defined(HAVE_CXXOX) 
      #include <unorderd_map> 
      typedef srd::unordered_map map; 
     #elif defined(HAVE_TR1) 
      #include <tr1/unordered_map> 
      typedef std::tr1::unordered_map map; 
     #else 
      #include <map> 
      typedef std::map map; 
     #endif 
    #elif defined(__SUNPROC_CC) 
     #include <map> 
     typedef std::map map; 
    #endif 

} //namespaces 
+2

而你的問題是? – robert 2010-12-22 14:26:17

+0

@robert我認爲他的意思是這是做到這一點的最佳方式。 – 2010-12-22 14:29:31

回答

3

這不會原因有二:

  1. 標題必須包含的外範圍爲namespace project { ... }。 (如果標題只包含模板和內聯函數,它可能無論如何都可以工作,但我不會指望它。)
  2. typedef在模板上不起作用。有一個解決方法是定義一個空的派生類。

所以,或許是這樣的:

#if defined(__GNUG__) 
    #if defined(HAVE_CXXOX) 
     #include <unordered_map> 
     #define MAP std::unordered_map 
    #elif defined(HAVE_TR1) 
     #include <tr1/unordered_map> 
     #define MAP std::tr1::unordered_map 
    #else 
     #include <map> 
     #define MAP std::map 
    #endif 
#elif defined(__SUNPROC_CC) 
    #include <map> 
    #define MAP std::map 
#endif 

namespace myproject { 
    template <class K, class V> 
    class map : public MAP<K, V> {}; 
} 

#undef MAP 
0

經過進一步閱讀它可能是值得investigatinng C++ 0x中新的「模板別名」的概念。這裏有一些未經測試的代碼作爲它如何工作的一個例子。

#if defined(__GNUG__) 
     #if defined(HAVE_CXXOX) 
      #include <unordered_map> 
      #define MAP std::unordered_map 
     #elif defined(HAVE_TR1) 
      #include <tr1/unordered_map> 
      #define MAP std::tr1::unordered_map 
     #else 
      #include <map> 
      #define MAP std::map 
     #endif 
#elif defined(__SUNPROC_CC) 
    #include <map> 
    #define MAP std::map 
#endif 

namespace internal { 

    template <typename K, typename V> 
    struct unordered_map { typedef MAP<K, V>; >; 

} //internal 

template <typename K, typename V> 
using unordered_map = typename internal::unordered_map<K, V>::type; 

在這裏看到更多的信息http://www2.research.att.com/~bs/C++0xFAQ.html#template-alias

0

定義的thornyard,包括與必然之間,以測試幾乎每一個編譯器更何況小版本和東西(喜歡的東西如:具有tuple_element GCC的某些特定版本中的另一個名稱),我採取了一種合理的方法:將解決方案委託給實際有選擇權和實施權的人。這意味着要麼使用類似Boost.TR1的包裝或「自己動手」。

我假設頭文件路徑類似於C++ 11中的代碼,如#include <header>所示。用戶比我更瞭解自己的環境,因此他可以例如:add Boost.TR1 to the include paths(或他選擇的另一個TR1實施)使事情更加無縫地工作。哎呀,即使只是指向一個具有「重定向」標題的文件夾,如果需要,它也可以轉發到<tr1/*>版本。等等。從本質上講,如果開發者已經爲你做出了犧牲,爲什麼還要經歷宏噩夢?

這讓我非常痛苦,因爲它允許我編寫「一次寫入」代碼,而不必每次都測試不同的編譯器,即使在次要版本中也是如此,並且還有助於使代碼向前兼容到C++ 11。

當然,雖然有一些技巧 - 取決於您對編譯器的假設,您可能需要使用諸如「using namespace tr1」技巧之類的技巧或(更好)交替和其他類型的技巧