2010-12-22 59 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”技巧之类的技巧或(更好)交替和其他类型的技巧