N
Ninereeds
I'm messing around with using mixin-layers (look for papers by Yannis
Smaragdakis and Don Batory) to define data structures. One issue is
that nodes tend to have pointers to other nodes - the pointers have to
point to the full node type, and have to be referenced before that
full node type is known.
One solution is to use the 'fixpoint construction' to get an apparent
circular dependency...
class c_Final : public c_Layer2< c_Layer1 <c_Final> > {};
I'm always a bit nervous about this, though, so I was wondering about
alternatives. It seemed to me that all I really need to do is to
declare the final node type in a base class, but define it in a
derived class.
So, I tried the following experiment...
class c_Base
{
public:
struct c_Full_Node;
struct c_Node
{
c_Full_Node *m_Parent;
};
};
class c_Derived1 : public c_Base
{
public:
struct c_Base::c_Full_Node : public c_Base::c_Node
{
int m_Data;
};
typedef c_Base::c_Full_Node c_Full_Node;
};
//class c_Derived2 : public c_Base
//{
// public:
// struct c_Base::c_Full_Node : public c_Base::c_Node
// {
// char m_Data;
// };
//
// typedef c_Base::c_Full_Node c_Full_Node;
//};
//////////
int main(int argc, char* argv[])
{
c_Derived1::c_Full_Node l_Node1;
l_Node1.m_Parent = 0;
l_Node1.m_Data = 0;
//c_Derived2::c_Full_Node l_Node2;
//l_Node2.m_Parent = 0;
//l_Node2.m_Data = 0;
return EXIT_SUCCESS;
}
The commented out code does not compile, for fairly obvious reasons -
it tries to create a second definition of c_Base::c_Full_Node.
This seems like a perfect solution to the problem to me, since it
doesn't give the appearance of peering into the future. I haven't
wrapped it up in templates to do real mixin layer stuff yet, but I
can't see any *additional* reasons why that shouldn't work.
What can I say. I've learned to think twice before saying "that would
never work" with C++, or I would never have even tried this
experiment.
That said, all I have proved is that it seems to work with Microsoft
Visual C++ 2003. This doesn't mean that it *should* work, according to
the standard.
So - can anyone tell me whether this is standard-compliant, portable
code? I haven't got a clue myself.
Smaragdakis and Don Batory) to define data structures. One issue is
that nodes tend to have pointers to other nodes - the pointers have to
point to the full node type, and have to be referenced before that
full node type is known.
One solution is to use the 'fixpoint construction' to get an apparent
circular dependency...
class c_Final : public c_Layer2< c_Layer1 <c_Final> > {};
I'm always a bit nervous about this, though, so I was wondering about
alternatives. It seemed to me that all I really need to do is to
declare the final node type in a base class, but define it in a
derived class.
So, I tried the following experiment...
class c_Base
{
public:
struct c_Full_Node;
struct c_Node
{
c_Full_Node *m_Parent;
};
};
class c_Derived1 : public c_Base
{
public:
struct c_Base::c_Full_Node : public c_Base::c_Node
{
int m_Data;
};
typedef c_Base::c_Full_Node c_Full_Node;
};
//class c_Derived2 : public c_Base
//{
// public:
// struct c_Base::c_Full_Node : public c_Base::c_Node
// {
// char m_Data;
// };
//
// typedef c_Base::c_Full_Node c_Full_Node;
//};
//////////
int main(int argc, char* argv[])
{
c_Derived1::c_Full_Node l_Node1;
l_Node1.m_Parent = 0;
l_Node1.m_Data = 0;
//c_Derived2::c_Full_Node l_Node2;
//l_Node2.m_Parent = 0;
//l_Node2.m_Data = 0;
return EXIT_SUCCESS;
}
The commented out code does not compile, for fairly obvious reasons -
it tries to create a second definition of c_Base::c_Full_Node.
This seems like a perfect solution to the problem to me, since it
doesn't give the appearance of peering into the future. I haven't
wrapped it up in templates to do real mixin layer stuff yet, but I
can't see any *additional* reasons why that shouldn't work.
What can I say. I've learned to think twice before saying "that would
never work" with C++, or I would never have even tried this
experiment.
That said, all I have proved is that it seems to work with Microsoft
Visual C++ 2003. This doesn't mean that it *should* work, according to
the standard.
So - can anyone tell me whether this is standard-compliant, portable
code? I haven't got a clue myself.