views:

155

answers:

3

Hello!

If I want to create a smart pointer to struct I do that:

 struct A
 {
  int value;
 };
 typedef boost::shared_ptr<A> A_Ptr;

So, I can write the following:

 A_Ptr pA0(new A);
 pA0->value = 123;

But, If I have a template struct like that:

 template<typename T>
 struct B
 {
  T value;
 };

And I want to write the following:

 B_Ptr<char> pB0(new B<char>);
 pB0->value = 'w';

So, How should I declare the B_Ptr ?

+4  A: 

If you are interested in a fixed template type for B, then I throw my support behind xtofl's answer. If you're interested in later specifying B's template argument, C++ doesn't allow you to do this (though it will be changed in C++0x). Typically what you're looking for is this kind of workaround:

template <typename T>
struct B_Ptr
{
    typedef boost::shared_ptr< B<T> > type;
};

B_Ptr<char>::type pB0 = ...;

(Thanks to UncleBens for the improvements.)

fbrereto
That's a good way to over complicate a simple answer.
Martin York
@Martin: How so? His wording of the question is vague enough that I'm not convinced he was looking for a fixed type, and my answer is a reasonable solution in the case he is not.
fbrereto
Or perhaps: `template <class T> struct T_Ptr{ typedef boost::shared_ptr<B<T> > type; }; T_Ptr<char>::type x;`
UncleBens
@UncleBens Yeah, I like that better; answer updated. Thanks!
fbrereto
@fbrereto: I find the question clear and concise. Why does this not work. You are adding another layer of indirection that is not required and just makes it harder to read without providing any benefit to a maintainer.
Martin York
+4  A: 

That would be

typedef shared_ptr< B<char> > B_Ptr;
B_Ptr p( new B<char> );
p->value = 'w';
xtofl
Are you sure that `B<char>*` is implicitly convertible to `shared_ptr<B<char> >`?
sellibitze
Classic shared_ptr error. It should be B_ptr p(new B<char>).
Dan Hook
@Dan: why? I can as well write `int i=0;` as `int i(0);`.
xtofl
There is a different between those two. The = syntax is called copy initialization. The other one is direct initialization. In case of shared_ptr the constructor that takes a pointer is explicit which means you *have* to use direct initialization.
sellibitze
@sellibitze: thanks. I didn't know that. Found <a href="http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-assignment-initializ/1051468#1051468">another question</a> on this, too.
xtofl
And since the direct initialization might light to `the most frustrating parse`, you often end up with `B_Ptr p = B_Ptr(new B<char>);`
Matthieu M.
+2  A: 

What you want is not yet possible in C++. You want "template typedefs" which will be known in C++0x as "alias declaration templates":

template<typename T>
struct A {};

template<typename T>
using APtr = boost::shared_ptr<A<T>>;  // <-- C++0x

int main() {
    APtr<int> foo;
}

I guess you could do something similar in C++98 with a macro if you really want to.

sellibitze