Thread: Multiple inheritance from same base template ambiguity

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    10

    Multiple inheritance from same base template ambiguity

    I have the following situation:

    I have a List class, made up by class ListNode that is inherited in classes that wants to be put in lists.

    Code:
    struct _List_node_base
    {
    	void _M_hook(_List_node_base* const __position);
    	void unhook();
    };
    
    
    template<typename _Tp>
    class ListNode : public _List_node_base
    {
            typedef _Tp*	pointer;
    public:
    	pointer GetNext();
    	pointer GetPrev();
    };
    
    
    template<typename _Tp>
    class List
    {
      ...
    };
    I also have a HashTable class which similar to lists have a HashNode class. The HashNode use ListNode in order to be put in a list in the appropriate hash slot.

    Code:
    template<typename _KeyType, typename _ObjectType>
    class HashNode : public ListNode<ObjectType>
    {
    public:
          _KeyType GetHashKey()
    };
    
    
    
    template<typename _KeyType, typename _ObjectType, typename _HashFunctionType>
    class HashTable
    {
    	  //example
    
    	template<typename _KeyType, typename _ObjectType, typename _HashFunctionType>
    	void HashTable<_KeyType, _ObjectType, _HashFunctionType>::Insert(_ObjectType *object)
    	{
    		uint pos = hashFunction(object->GetHashKey(), tableSize);
    
    		hashTable[pos].PushBack(object);
    	}
    
    };

    I have a class that wants to be both listable and hashable.

    Code:
    class A : public HashNode<SomeKeyType_t, A>, public ListNode<A>
    {
    	...
    };
    The problem is that the compiles complains about that the members in _List_node_base has an ambiguous base of class A.

    Both in the Hash class and the List class, they use methods in ListNode and _List_node_base directly on class A.

    Basically, I want to make class A both hashable and listable but the ListNode functionality of HashNode should not be exposed outside the implementation of class HashTable.

    Also the point of the classes are that they must be self contained and not use any dynamic allocation, no copying or allocation are allowed. Otherwise this would have been solved by creating a container class.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    A warning, though it is not likely to be related to your problem: names that begin with an underscore followed by an uppercase letter, or that contain consecutive underscores, are reserved to the implementation for any use. That is, unless you are implementing a C++ compiler or the C++ standard library, you should not be using names such as _List_node_base and __position.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    After fixing the problem with underscores, use your base class virtual. That will address the ambiguity your compiler is complaining about.

    Generally, however, I seriously suggest you rethink your design. Generally, with a templated list class, there is no reason for data elements to know they are stored in the list. All you are doing is setting yourself up to experience the complications of a fragile base class.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Registered User
    Join Date
    Dec 2010
    Posts
    10
    Quote Originally Posted by grumpy View Post
    After fixing the problem with underscores, use your base class virtual. That will address the ambiguity your compiler is complaining about.

    Generally, however, I seriously suggest you rethink your design. Generally, with a templated list class, there is no reason for data elements to know they are stored in the list. All you are doing is setting yourself up to experience the complications of a fragile base class.
    Since this is an intrusive list class, classes that want to be listable must own their own list data.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It is unclear why you can't just inherit only from Hashnode?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    10
    Quote Originally Posted by anon View Post
    It is unclear why you can't just inherit only from Hashnode?
    Because class A should be able to put in a list as well as being able to be used in a hash table, however both the normal list and the hash table use the list implementation. Basically the object should have the list members twice.

    I've redesigned my implementation so that HashNode is now a class member instead. HashNode still inherits List but the hash table implementation works directly on the HashNode instead. This way you can single out the List member for the hash table. HashNode must therefore have a pointer to the class where it is a member, but that's how it is. The implmentation of hash table is now more like a "normal" implmentation where you have an abstract data type in a container.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by TotalTurd View Post
    Since this is an intrusive list class, classes that want to be listable must own their own list data.
    My point is that it would be better to design your list class so it is not intrusive on the data it is listing.

    One basic guideline of class design: make your class no more intrusive than it needs to be. Forcing derivation from a particular base class is about as intrusive as it is possible to be.

    A list (of any type) generally does not need cooperation of the listed objects - if the list class is designed well.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Reference Counting
    By Dae in forum C++ Programming
    Replies: 10
    Last Post: 08-13-2009, 07:34 AM
  2. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Multiple Inheritance Ambiguity
    By FillYourBrain in forum C++ Programming
    Replies: 21
    Last Post: 08-23-2002, 10:31 AM
  5. Multiple virtual inheritance
    By kitten in forum C++ Programming
    Replies: 3
    Last Post: 08-10-2001, 10:04 PM