Каковы различия между std, tr1 и boost (как пространства имен и/или библиотеки)?
Сначала я думал, что они все одинаковые, но оказалось, что это неправильно. Так может кто-нибудь кратко объяснить различия между этими тремя? Например:
-
std::bind
(новейшее, следующее поколение С++)
-
std::tr1::bind
(старый, расширение С++ std)
-
boost::bind
(полностью отдельная библиотека)
или std::shared_ptr
, std::tr1::shared_ptr
и boost::shared_ptr
,... etc
Обновление
bind
, shared_ptr
являются примерами, которые помогают прояснить мой вопрос. Я хотел понять общие различия между этими тремя пространствами имен. Существует несколько библиотек, которые существуют во всех трех пространствах имен, и, по-видимому, bind
является одним из примеров, а также shared_ptr
.
В каких пространствах имен я должен придерживаться? Я лично предпочитаю библиотеку из std::
, так как это будет следующий стандарт С++ (С++ 0x).
Ответы
Ответ 1
1 - std::bind
является стандартным именем для него. Это будет имя, которое вы используете для библиотек, совместимых с С++ 11. Список библиотек в стандартизованном С++.
2 - std::tr1::bind
- это пространство имен С++ Technical Report 1. Между С++ 03 и С++ 11 был С++ Technical Report 1, в котором предлагались дополнительные библиотеки и улучшения. Большинство из них уже существовали в Boost в то время, и некоторые из этих изменений библиотеки были приняты в стандарте С++ 11, например <regex>
и <functional>
(который содержит std::bind
). Пространство имен std::tr1
использовалось для дифференциации библиотек в их состоянии незавершенного производства, в отличие от всего, стандартизованного в пространстве имен std
.
3 - boost::bind
для bind
в пространстве имен boost
, если вы используете Boost. Boost охватывает гораздо больше, чем то, что находится в TR1, и что я в С++ 11-й библиотеке. Список всех библиотек в Boost от версии 1.52.0
Большая часть того, что была в TR1, была стандартизирована и находится в пространстве имен С++ 11 std
, а С++ 11 содержит больше библиотек, чем упоминалось в TR1, которые были адаптированы из конструкций Boost, например поддержка потоков, определенная в <thread>
.
Часть того, что определяет, что вы можете использовать, и какое пространство имен, которое вы можете использовать сейчас, зависит от вашего компилятора. Я не помню, но я думаю, что более свежие реализации GCC-g++ начали использовать пространства имен std
для новых библиотек С++ 11, но для активации этого может потребоваться другой флаг компилятора. Тем не менее, они все равно будут поддерживать пространство имен std::tr1
. Visual С++ 2010 перенесла то, что ранее было в std::tr1
, в обычное пространство имен std
, но Visual С++ 2008 все еще использовала std::tr1
.
Ответ 2
Если вы хотите использовать bind (или любой другой для этого вопроса), хорошей функцией является переименование пространства имен, вот пример:
namespace MyNamespace = boost;
void DoSomething(void)
{
MyNamespace::bind( ... );
}
Теперь, если вы измените MyNamespace:
namespace MyNamespace = std::tr1;
В следующих случаях используется std::tr1::bind
.
namespace MyNamespace = std::tr1;
void DoSomething(void)
{
MyNamespace::bind( ... );
}
Вы должны, конечно, использовать MyNamespace для элементов, которые вы хотите легко изменить в пространстве имен в будущем, если вы знаете, что хотите std:: tr1, вы должны использовать его напрямую и никогда не использовать псевдоним.
Ответ 3
Ты в значительной степени получил его в своем вопросе. Я мог бы просто скопировать/вставить ваш пример и правильно ответить на ваш вопрос. Только две вещи действительно выделяются как необходимость расширения:
1) Точно КАК и почему std:: расширяется tr1. TR1 является "Техническим докладом 1" и является первым официальным набором расширений библиотек, предложенным комитетом по стандартам одной из его подгрупп. Так что это немного больше, чем просто расширение стандарта.
2) boost:: bind фактически ведет себя иначе, чем std:: bind, по крайней мере, на некоторых системах. Я не знаю, если это стандартно, но не в выражениях lambda MSVC, а std:: bind ведут себя очень плохо друг с другом. Возможно, некоторые другие способы тоже, я не помню, так как я сделал это для использования boost:: bind, а не std:: bind. Параметр шаблона возвращаемого значения часто игнорируется с помощью std:: bind на msvc, так что вы получаете ошибки о том, что не существует return_value<f>::type
(или что-то еще), когда вы указали его с помощью std::bind<type>(...)
. Никогда не беспокоился о том, чтобы определить точную разницу в поведении, поскольку boost:: bind уже попал в наш обычный словарь, и мы знали, как его использовать.
Ответ 4
Это не должно иметь большого значения, так как большие части следующего стандарта С++ на самом деле были унаследованы от Boost. Поэтому, если у вас есть std::bind
и не нужно быть совместимым с другими компиляторами, просто используйте его. boost::bind
хорош, если вы хотите быть независимым от компилятора. Я думаю, что std::tr1::bind
не имеет каких-либо преимуществ перед другими двумя, если они доступны: он нестандартен по отношению к С++ 03 и С++ 0x.