jarmond
jarmond

Reputation: 1382

How should I put native C++ pointers in .NET generic collections?

In C++/CLI it is not possible to put pointers to native C++ classes in managed .NET generic collections, e.g.

class A {
public:
    int x;
};

public ref class B {
public:
    B()
    {
        A* a = GetPointerFromSomewhere();
        a->x = 5;
        list.Add(a);
    }
private:
    List<A*> listOfA; // <-- compiler error (T must be value type or handle)
}

is not allowed. I could of course use std::vector<A*> list; but then I could only make list a member of a managed class by using a pointer and it feels unnatural to use pointers to STL containers.

What is a good way to store native C++ pointers in .NET generics? (I'm not interesting in resource management here; the object the pointer points to is managed elsewhere)

Upvotes: 4

Views: 1727

Answers (1)

jarmond
jarmond

Reputation: 1382

The method I've been using is to wrap the pointer in managed value class, and then overload the dereferencing operator:

template<typename T>
public value class Wrapper sealed
{
public:
    Wrapper(T* ptr) : m_ptr(ptr) {}
    static operator T*(Wrapper<T>% instance) { return instance.m_ptr; }
    static operator const T*(const Wrapper<T>% instance) { return instance.m_ptr; }
    static T& operator*(Wrapper<T>% instance) { return *(instance.m_ptr); }
    static const T& operator*(const Wrapper<T>% instance) { return *(instance.m_ptr); }
    static T* operator->(Wrapper<T>% instance) { return instance.m_ptr; }
    static const T* operator->(const Wrapper<T>% instance) { return instance.m_ptr; }
    T* m_ptr;
};

I can then use the pointer naturally as follows:

public ref class B {
public:
    B()
    {
        A* a = GetPointerFromSomewhere();
        a->x = 5;
        list.Add(Wrapper<A>(a));
        Console.WriteLine(list[0]->x.ToString());
    }
private:
    List<Wrapper<A>> listOfA;
}

Any improvements welcomed...

Upvotes: 7

Related Questions