Используйте макрос #define в C ++ для выбора реализаций из разных пространств имен - PullRequest
3 голосов
/ 06 января 2012

Многоплатформенный движок, который мы разрабатываем для нашей игры, использует EASTL для замены STL из-за памяти, производительности и переносимости. EASTL можно найти здесь:
http://www.open -std.org / ОТК1 / SC22 / wg21 / документы / документы / 2007 / n2271.html

Поскольку Visual Studio действительно хорош для отладки STL, мы не используем EASTL в Windows, пока движок находится в разработке. Также некоторые контейнеры STL, такие как std :: queue, std :: deque, ... недоступны в EASTL. Потому что это не имеет значения, мы также используем eastl :: string в Windows, потому что это хорошо для отладки.

То, что мы делаем до сих пор, это

#if (GIN_USE_EASTL)
    #define ginstl eastl
#else
    #define ginstl std
#endif

и GIN_USE_EASTL определяется как 0 в Windows. Двигатель называется Ginkgo, отсюда и происходит GIN.
Мы используем списки, векторы, ... как это

ginstl::list myList;
ginstl::vector myVector;

, который работает довольно хорошо. Но когда мы используем строку или очередь, по причинам, которые я объяснил выше, мы должны написать

eastl::string myString;
std::queue myQueue;

что является причиной, почему я публикую здесь, потому что это не оптимально! Я хочу использовать макрос ginstl :: для всего движка, не думая о том, какую реализацию использовать. Поэтому мой подход к проблеме был следующим:

#if (GIN_USE_EASTL)
    #define ginstl::list eastl::list
    #define ginstl::vector eastl::vector
    #define ginstl::string eastl::string
    #define ginstl::queue std::queue
#else
    #define ginstl::list std::list
    #define ginstl::vector std::vector
    #define ginstl::string eastl::string
    #define ginstl::queue std::queue
#endif

Но, к сожалению, это не работает, потому что :: не допускается в макросе #define. Есть ли способ достичь того же (можно указать, какую реализацию я хочу использовать для конкретной структуры данных) как-то иначе? Я мог бы пойти на

#define ginstl_list eastl::list

но я бы предпочел структуру сверху! Есть ли способ (кроме написания собственного препроцессора) обойти проблему?

Ответы [ 3 ]

6 голосов
/ 06 января 2012

А как же using namespace:

namespace ginstl
{
#if (GIN_USE_EASTL)
    using eastl::list
    using eastl::vector
    using eastl::string
    using std::queue
#else
    using std::list
    using std::vector
    using eastl::string
    using std::queue
#endif
}
5 голосов
/ 06 января 2012

Дальнейшее развитие на пути Mark B (нет необходимости перечислять все используемые типы):

namespace ginstl
{
#if (GIN_USE_EASTL)
    using namespace eastl;
#else
    using namespace std;
#endif
    using eastl::string
    using std::queue
}
3 голосов
/ 06 января 2012

Если вы используете псевдонимы пространства имен вместо макросов:

#if (GIN_USE_EASTL)
    namespace ginstl = eastl;
#else
    namespace ginstl = std;
#endif

Затем вы можете сделать это:

using namespace ginstl;
using std::queue;
using std::deque;

list<int> x; // from eastl or std, depending on GIN_USE_EASTL
queue<int> y; // always from std
...