views:

528

answers:

6

How can I cast a boost::shared_array<char> to boost::shared_array<const char>?

+1  A: 

You can't.

As both types are based on a template, both types are completely different for the compiler.

frunsi
A: 

Such compiler-generated casting can not be possible.

The internals of the class with const-qualified template parameter may differ dramatically from the class without one, due to template specialization feature.

Moreover, the use of such feature is sometimes a background for compile-time checks that merely may not allow instantiation of A<const T> type for every case where A<T> type is correct.

Pavel Shved
Not possible? Yet boost::shared_ptr supports implicit conversion from derived to base types (and non-const to const) and all sorts of casts.
Alex B
It indeed does support *conversion*. But it can't be *type-casted*.
Pavel Shved
It does support casts, unless you mean something else entirely. E.g., `boost::shared_ptr<Derived> ptr(boost::static_pointer_cast<Derived>(base_shared_ptr));`
Alex B
+1  A: 

I think you can't. In case you really need it though, you can create a custom smart-pointer class. Hints for that can be found here.

Space_C0wb0y
+2  A: 

The other answers are correct, you can't and you shouldn't.

Besides, are you sure you want a boost::shared_array<const char> and not a const boost::shared_array<char>?

Practically, this works:

boost::shared_array<char> acz;
boost::shared_array<const char>& acz2 = reinterpret_cast< boost::shared_array<const char>& >(acz);

BUT it is not a good idea and only works if boost::shared_array and boost::shared_array have the same implementation. Templates can be partially specialized:

template<class T>
struct TwoImplementations {
    int m_nIntMember;
};

template<>
struct TwoImplementations< const T > {
    double m_fDoubleMember;
};

Doing a reinterpret cast between TwoImplementations<int> and TwoImplementations<const int> is just wrong.

Sebastian
Never use such a reinterpret_cast, especially in this case! Generally speaking, reinterpret_cast is 99% not portable.
rmn
I know that and acknowledge it in my post. So please don't downvote. It is a language feature, it can work and in 1% of the cases may even be useful.
Sebastian
@rmn: One size does not fit all, I agree that in this place it's a bad idea, but never say never.
Joe D
+1  A: 

You could use the get() method to get the underlying char*, which is auto convertible to a const char* - but don't assign it to another shared_array because then you'll have the data deleted twice. Just use it as you need it.

like this:

boost::shared_array<char> x(new int[13]);
const char *y = x.get();
rmn
+3  A: 

Since shared_array has no add_ref method you could emulate it as follows:

struct MagicDeleter {
  MagicDeleter( boost::shared_array<char> ptr ) : ptr(ptr) {};
  template<typename T> void operator()(T*) {} 
protected:
  boost::shared_array<char> ptr;
};

...

boost::shared_array<char> orig_ptr( some_val );
boost::shared_array<const char> new_ptr( orig_ptr.get(), MagicDeleter(orig_ptr) );
Kirill V. Lyadvinsky