Одним из улучшений вашего примера кода и ответом на ваш первый вопрос является использование идиомы " template typedef ":
#if HAVE_STD_TR1_SHARED_PTR
template <class T>
struct SharedPtr {
typedef std::tr1::shared_ptr<T> Type;
};
#elif HAVE_BOOST_SHARED_PTR
template <class T>
struct SharedPtr {
typedef boost::shared_ptr<T> Type;
};
#else
# error "No definition for shared_ptr found"
#endif
// Declare a shared_ptr using our wrapper classes, saving us from having to care
// where shared_ptr comes from:
SharedPtr<int>::Type my_shared_int(new int(42));
Основная проблема в этом заключается в необходимости использовать нотацию :: Type. Это просто потому, что в C ++ в настоящее время нет возможности использовать typedef для шаблона. У вас может быть typedef для шаблона типа instance , но здесь важно сохранить универсальность.
Что касается того, предпочитаете ли вы TR1 Boost, я бы сказал, да. Теперь, когда компиляторы поставляются с частичной поддержкой C ++ 0x, я бы сказал, что вы должны также проверить на std :: shared_ptr и предпочесть это любому другому.
Вам может понадобиться четвертая typedef, если есть компиляторы, которые имеют shared_ptr где-то еще. Я не знаю такого компилятора, но некоторый код C ++, который я поддерживаю, делает нечто похожее на то, о чем вы спрашиваете с обычным расширением slist
для стандартной библиотеки C ++ для односвязных списков. Старые версии g ++ помещают его в глобальное пространство имен, современные g ++ помещают его в специфическое для компилятора пространство имен __gnu_cxx
, и мы даже нашли такое, которое ошибочно поместило его в std
!