Использование классов C ++, таких как функция, которая может быть определена в нескольких разных местах. - PullRequest
8 голосов
/ 02 марта 2011

Между C ++ 0x, C ++ 03 TR1 и boost некоторые вещи, такие как function и bind, могут быть определены в 3 разных местах в зависимости от компилятора, например, для пакета функций VC pre VC9 у вас есть версии boost, а затем вы получаете они в но в пространстве имен std :: tr1 ::, а VC10 перемещает это только в пространство имен std ::.

В настоящее время мой существующий код использует более старые версии Boost в пространстве имён boost ::, однако, поскольку во многих моих приложениях и библиотеках все компоненты Boost, которые я использовал, теперь находятся в tr1 и C ++ 0x, id, если возможно, удалить усиление зависимости от них при сохранении обратной совместимости со старыми версиями компилятора.

Однако я не уверен, как сделать так, чтобы мой код находил, включал и затем имел доступ к правильным версиям :( Одна вещь, которую я рассмотрел, - это использование макросов, таких как _MSC_VER, чтобы увидеть, включает ли компилятор нужные мне классы, (возвращаясь к tr1 и затем увеличивая при необходимости), а затем используйте материал «using somenamespace :: someclass;» для перемещения рассматриваемых классов в пространство имен std ::.

Проблема в том, что в некоторых случаях это может привести к поломке, и я даже не уверен, как определить, установлен ли на VC9 пакет функций или установлен SP1 :( Я тоже не уверен в аккуратности чтобы сделать это, возможно, предоставьте свой собственный функционал .hpp, который делает требуемую «магию»?

Главное, я хочу начать писать свой код для новых стандартов, но так, чтобы он работал с минимальными усилиями на старых компиляторах.

Ответы [ 3 ]

8 голосов
/ 02 марта 2011

Boost . TR1 уже делает это за вас - у него есть логика обнаружения компилятора / версии, чтобы использовать реализацию TR1 вашего компилятора, если она доступна для вашей платформы, или использовать различные соответствующие Boostбиблиотеки для эмуляции TR1, если нет:

Эта библиотека сама не реализует компоненты TR1, скорее это тонкая оболочка, которая будет включать реализацию TR1 вашей стандартной библиотеки (если она есть), в противном случае она будет включатьэквиваленты Boost Library и импортируйте их в пространство имен std::tr1.

3 голосов
/ 02 марта 2011

Из вашего поста кажется, что вас больше всего волнует VC ++. Если это так, то я думаю, что использование препроцессорных определений на основе _MSC_VER, вероятно, является наиболее прямым решением. Как вы намекали, просто выясните, какие версии были первыми, чтобы обеспечить различные функции и включить соответствующий заголовок.

Что касается доступа к ним в вашем коде, я бы просто использовал несколько typedef с разными типами в зависимости от включенного заголовка. Если версии библиотек boost, tr1 и C ++ 0x предоставляют одинаковые (или достаточно похожие) интерфейсы, это должно "просто работать". Хотя, если тип является шаблоном класса, обычные typedefs не будут работать, и вам придется прибегнуть к # define.

Иногда прямое движение - это хорошо. Возможно, не стоит делать это слишком сложным. (Если вы хотите поддерживать больше, чем просто VC ++, вам, вероятно, придется усложниться.)

Возможно, что-то вроде этого (как первая мысль):

#ifdef _MSC_VER
  #if _MSV_VER >= VERSION_WITH_CXX0X
    #include <function>
    #define FUNCTION_NAMESPACE std
  #elif _MSV_VER >= VERSION_WITH_TR1
    #include <tr1/function>
    #define FUNCTION_NAMESPACE std::tr1
  #else
    #include <boost/function.hpp>
    #define FUNCTION_NAMESPACE boost
#else
  #error The current compiler is not supported.
#endif

void func();

FUNCTION_NAMESPACE::function<void ()> funcobj(func);

Хотя мне не нравится использовать #define для получения пространства имен, я не могу думать о другом способе преодоления моих проблем. Могу поспорить, что есть один.

0 голосов
/ 02 марта 2011

Поскольку вы уже используете Boost, рассмотрите возможность использования макросов, которые Boost.Config предоставляет , для проверки потенциально поддерживаемых функций. В частности, взгляните на макросы BOOST_HAS_TR1_* и макросы BOOST_NO_*.

Обратите внимание, что вы должны проверить отдельные функции, поскольку не все реализации TR1 и C ++ 0x поддерживают все функции этих спецификаций.

...