iammilind
iammilind

Reputation: 69998

Template specialization for smart pointer exactly as normal pointer

Following code demonstrates the problem:

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 is specialized for pointer types. Now at some places, I use smart pointer (say shared_ptr), which causes problem as shown in example.

One way is to copy the full struct A<T*> and rewrite for struct A<shared_ptr<T>>. Is there any elegant way to invoke A<T*> type for shared_ptr<> also ?

I am hopeful for following approach:

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

Is there any problem with this approach ?

[The only potential problem will occur with following type of usage:

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>"
};

Assume that, as of now this is not a concern.]

Upvotes: 3

Views: 1218

Answers (1)

bdonlan
bdonlan

Reputation: 231203

With boost, you could make use of the has_dereference type trait and 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 */ };

Upvotes: 6

Related Questions