Специализация шаблона для умного указателя в точности как обычного указателя - PullRequest
3 голосов
/ 22 ноября 2011

Следующий код демонстрирует проблему:

template<typename T>
struct A {
  // few members and methods...
};

template<typename T>
struct A<T*> {
  // different members and methods
};

A<int> ai; // invokes A<T>
A<int*> ap; // invokes A<T*>
A<shared_ptr<int>> as; // oops ! invokes A<T>

A специализируется для типов указателей. Теперь в некоторых местах я использую умный указатель (скажем, shared_ptr), что вызывает проблему, как показано в примере.

Один из способов - скопировать полную struct A<T*> и переписать для struct A<shared_ptr<T>>. Есть ли какой-нибудь элегантный способ вызвать A<T*> type для shared_ptr<> также ?

Я надеюсь на следующий подход:

template<typename T>
struct A<shared_ptr<T>> : public A<T*> { /* empty */ };

Есть ли проблемы с этим подходом?

[Единственная потенциальная проблема возникает при использовании следующего типа:

struct A<T*> {
  T* p;  // for A<int*> ... "typeof(p) = int*"
};

struct A<share_ptr<T>> : A<T*> {
  // oops! the "typeof(p)" is still "int*" and not "shared_ptr<int>"
};

Предположим, что на данный момент это не проблема.]

1 Ответ

6 голосов
/ 22 ноября 2011

С бустом вы можете использовать черты типа has_dereference и MPL if_:

template<typename T>
struct Aobj { /* T is not a pointer */ };
template<typename T>
struct Aptr { /* T is a pointer-like type */ };

template<typename T>
struct A : public
  boost::if_<boost::has_dereference<T>, Aptr<T>, Aobj<T> >::type
{ /* implementation provided by base */ };
...