4

I'd like a pointer wrapper class that acts just like a raw pointer but also saves a special integer along with the pointer (Type's index in the array it came from)

I managed to have it behave mostly like a pointer. I am aware that the pointer comparison solution might not be optimal but that's not my main problem. I want the wrapper to be constructed with 2 parameters(pointer,indexToArr), unless the pointer is NULL - then I don't care about indexToArr.

The problem I'm trying to solve is how to allow returning NULL just like a normal pointer allows. current solution uses an ASSERT. But I want something that works in compile-time. something in the spirit of a specialized template method - allowing only NULL as its argument.

Current version:

class PtrWrapper
{
public:
    PtrWrapper(Type* ptr, int indToArr) 
        : m_ptr(ptr), m_indexToArr(indToArr){}

    //allow returning NULL, only NULL
    PtrWrapper(Type* ptr) : m_ptr(NULL), m_indexToArr(-1) {ASSERT(ptr == NULL);}

    Type* operator->() const {return m_ptr;}
    Type& operator*() const {return *m_ptr;}
    int IndexToArr() const {return m_indexToArr;}

    //for pointer comparison
    operator Type*() const {return m_ptr;}

private:
    Type* m_ptr;
    int m_indexToArr;
};

Any ideas, suggestions?

Thanks, Leo

Leo
  • 309
  • 3
  • 8
  • 1
    Why do you need parameter in the second constructor? It is not used. – Alex F Aug 24 '11 at 13:05
  • 1
    Note that at compile time your compiler does not and cannot know if your PtrWrapper instance m_ptr member is null or not -it's a runtime property of the object. – AndrzejJ Aug 24 '11 at 13:07
  • I accept that. return NULL compile time case is sufficient for me. the 2nd param should be used, my mistake. – Leo Aug 24 '11 at 13:40

2 Answers2

5
template<typename Type>
class PtrWrapper
{
    typedef struct { } NotType;
public:
    Ptr() { }
    Ptr(const NotType* nullPtr) { }
    Ptr(Type* p, int index) { }
};

You can exploit the fact that literal NULL / 0 can be auto-cast to any pointer type. Create a type that is NOT T, and a constructor which takes a single pointer to that type which nobody will ever use. Now you can handle PtrWrapper<T> x(NULL); explicitly.

Of course as others have said, this is only going to work if NULL is known at compile-time.

tenfour
  • 36,141
  • 15
  • 83
  • 142
  • Beautiful, thanks. Btw, any difference between `struct NotType{}` vs `typedef struct{} NotType` ? – Leo Aug 24 '11 at 13:33
  • 2
    @Leo https://stackoverflow.com/questions/612328/difference-between-struct-and-typedef-struct-in-c BTW, since you are back in 2011 you should invest in Bitcoin – Jake Mar 15 '18 at 18:05
1

Simply make a default constructor with no arguments that initializes your pointer to NULL, but make sure to have some checks in your operator* and operator-> for a NULL pointer.

Do the following:

PtrWrapper(Type* ptr) : m_ptr(ptr), m_indexToArr(0) {ASSERT(ptr != NULL);}
PtrWrapper() : m_ptr(NULL), m_indexToArr(-1) {ASSERT(ptr == NULL);}
Jason
  • 31,834
  • 7
  • 59
  • 78
  • I want this code to work: PtrWrapper foo() {return NULL;} I want compile time check for that to be only NULL, not a valid pointer (in which case an index must be supplied) – Leo Aug 24 '11 at 13:08