3

I'm trying to use a class to group all the parameters of a template data structure, in particular an intrusive AVL tree. The user would do something like this:

struct MyEntry {
    MyEntry *parent;
    MyEntry *child[2];
    int balance;
    int value;
};

struct MyAvlTreeParams {
    typedef MyEntry entry_type;
    static constexpr auto parent_member = &MyEntry::parent;
    static constexpr auto child_member = &MyEntry::child;
    static constexpr auto balance_member = &MyEntry::balance;
    ... // comparators also come here which compare MyEntry::value
};

AvlTree<MyAvlTreeParams> tree;
MyEntry entry1, entry2;
entry1.value = 6;
entry2.value = 8;
tree.insert(&entry1);
tree.insert(&entry2);

But there is a problem with the member pointers in MyAvlTreeParams. This sample demonstrates it:

struct A {
    int x;
};

struct B {
    static constexpr auto member = &A::x;
};

int main ()
{
    A a;
    (a.*(B::member)) = 6;
    return 0;
}

This works with clang++ 3.1, but g++ 4.7.2 fails to link with the error:

/tmp/ccGXGIOl.o:a.cpp:function main: error: undefined reference to 'B::member'

The error is fixed by adding the following declaration some place after the definition of struct B (see this question):

constexpr int (A::*(B::member));

To see how this becomes problematic in my case, all the following would need to be added whenever the AVL tree is used:

constexpr MyEntry * MyEntry::*(MyAvlTreeParams::parent_member);
constexpr MyEntry * (MyEntry::*(MyAvlTreeParams::child_member))[2];
constexpr int MyEntry::*(MyAvlTreeParams::balance_member);

Is there any way to do this without such information-less boilerplate code, or something different which achieves the same goals of grouping parameters (i.e. not just passing all the members as template parameters)?

Community
  • 1
  • 1
Ambroz Bizjak
  • 7,809
  • 1
  • 38
  • 49

0 Answers0