Home > Back-end >  Workaround for using a private struct
Workaround for using a private struct

Time:01-27

I am using an engine for my console application. This engine can not be changed. The engine contains a class called Mesh. There's a public method in this class findBoundaryLoops() which I'm using in my class (which is not part of the engine) but I have to pass a parameter to this method which type VertexLoop is defined as a private attribute. I'm not sure that I explain it well, so there's a representation of the code:

Mesh.h:

class Mesh final
{
private:
    ...
    struct VertexNode
    {
        Edge connectingEdgeWithNext;
        Vertex vertex;
        VertexNode* prev;
        VertexNode* next;

        float angle;
    };

    struct VertexLoop
    {
        VertexNode* firstNode;
        uint32_t nodeCount;
        template<typename Callable>
        void forEachNode(Callable&& f)
        {
            VertexNode* n = firstNode;
            for (uint32_t i = 0; i < nodeCount;   i, n = n->next)
            {
                f(n);
            }
        }
    };
    ...

public:
    ...
    void findBoundaryLoops(memory::MemoryArena& arena, vector<VertexLoop>& loops) const;
    ...
};

I have to use the findBoundaryLoops() method, but the VertexLoop struct is private. Is there a workaround or something to solve this problem?

CodePudding user response:

This answer has two parts. Below I will show you how to access the type declared in the private section. But I think the important point, and thats why I put it first, is to realize that you should not need the below solution. Anybody can access VertexLoop. The name is private the type not. There was no point to declare it in the private section in the first place. If the type appears on the signature of a public method you can as well put it in the public section.

If this is library code or generated code, then either you misunderstand how to use it, or it can be considered broken.


Simpler example:

#include <vector>

struct foo {
    private:
        struct bar{};
    public:
        void f(std::vector<bar>&){}
};

Now we write a trait that given a member function of foo with a single vector parameter tells us the value_type of that vector. Then we instantiate it with a pointer to foo::f to get an alias to bar:

template <typename X> 
struct bar_type;

template <typename T> struct bar_type< void(foo::*)(std::vector<T>&)> { using type = T; };

using public_bar = bar_type<decltype(&foo::f)>::type;

Using it:

int main() {
    std::vector<public_bar> v;
    foo f;
    f.f(v);
}

Live Demo

Maybe worth to note that this is by no means comparable to "dirty hacks" by which one can access private members of a class (yes they do exist). This is not a hack, it is perfectly fine partial specialization of a trait to get the parameter type of a public method.


TL;DR Just don't do it. Move VertexLoop to the public section.

  • Related