1

I made a Qt library that is built on longstanding abstractions like QSharedDataPointer and QSharedData. So when I needed an ordinary shared pointer it made sense to go with QSharedPointer for consistency.

I'm now using this in a C++11 project. In order to make the code more standard, I'm switching over to shared_ptr for all of its local subsystems.

A C++11 dependency within the library itself isn't necessarily desirable, so it felt like you should be able to pick which kind of shared pointer you wanted to use. As a first cut just to move ahead I tried this method suggested in Flexibility of template alias in C++0x (admittedly a C++11 dependency itself, but I could use the preprocessor via a compiler flag in non-C++11 builds)

#if THINKERQT_USE_STD_SHARED_PTR

#include <memory>
template<class T>
using shared_ptr_type = std::shared_ptr<T>;

#else

#include <QSharedPointer>
template<class T>
using shared_ptr_type = QSharedPtr<T>;

#endif

Unfortunately the pointer classes picked different names for the methods. Notably, accessing the contained pointer is done by .get() in shared_ptr and by .data() in QSharedPointer.

I was going to make an extractor, some kind of shared_ptr_type_get<> but then noticed that one can achieve effectively the same thing (in cases where the contained pointer is not null, and I can test for null via boolean coercion) with:

&(*ptr)

It's a bit of a speed bump if you're reading the code, and the sort of thing someone might try and optimize out (then quickly figure out that won't work). But other than the WTF factor, it seems harmless enough...is it?

Community
  • 1
  • 1

1 Answers1

3

I use this in a project of mine as well, and there is nothing wrong in using that besides readability as you already noticed. And as Mike Seymour pointed out, you should always check that ptr is not a null pointer first.

I use following idiom in most cases:

if( shared_ptr_type ptr = funcReturnsSharedPtr() )
{
    funcAcceptsRawPtr(&*ptr);
}

Its pretty much guaranteed that this will compile and function correctly no matter what kind of shared pointer type you use for shared_ptr_type since any reasonable shared pointer class will overload operator*.

smerlin
  • 6,446
  • 3
  • 35
  • 58
  • +1 Glad to see I'm not the only one. (I like linking to questions like this from within the code in case someone reads and goes *Why'd he do that?*) But due to my own idioms, I'd use `boost::optional< shared_ptr >` in those interfaces where a null is possible/meaningful. This allows the type system to get involved during compilation in making sure anyone who needs to test for the absence of a pointer is doing so. It works well for me, though I name my routines things like "funcReturnsSharedPtrMaybeNull" if I'm in a context w/o optional allowed and I want to call attention to potential nulls – HostileFork says dont trust SE Jun 22 '12 at 20:28