Home > Software engineering >  Calling function that was declared virtual in interface (and implemented in derived class) inside ba
Calling function that was declared virtual in interface (and implemented in derived class) inside ba

Time:11-26

I have the following inheritance model:

   interface      abstract class   concrete derived class
_________________________________________________________
IPriorityQueue -> APriorityQueue -> UnsortedPriorityQueue

My member function was declared purely virtual in the interface. In the abstract class, I want to use size() to already implement empty(), since if size = 0, then the priority queue is empty. size() is properly implemented in the derived class.

#include <list>

template <typename K, typename V>
class   IPriorityQueue
{
    public:
        virtual int     size(void)  const = 0;
        virtual bool    empty(void) const = 0;
};

template <typename K, typename V>
class   APriorityQueue : virtual public IPriorityQueue<K, V>
{
    public:
        bool    empty(void) const { return (!size()); }
};

template <typename K, typename V>
class   UnsortedPriorityQueue : virtual public APriorityQueue<K, V>
{
    private:
        std::list<V>    _list;
    public:
        int             size(void)  const { return (this->_list.size()); }
};

int main()
{
    UnsortedPriorityQueue<int, char>    test;
}

However, I get the following error:

../../libft/APriorityQueue.hpp:49:37: error: there are no arguments to 'size' that depend on a template parameter, so a declaration of 'size' must be available [-fpermissive]
   bool empty(void) const { return (!size()); }
                                     ^~~~
../../libft/APriorityQueue.hpp:49:37: note: (if you use '-fpermissive', G   will accept your code, but allowing the use of an undeclared name is deprecated)

I read in some other answers on StackOverflow that one has to specify the namespace, so I modified it the following way:

        bool    empty(void) const { return (!IPriorityQueue<K, V>::size()); }

But now I get a linker error complaining that IPriorityQueue<K, V>::size() is not implemented:

main.o:main.cpp:(.text$_ZNK14APriorityQueueIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5emptyEv[_ZNK14APriorityQueueIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5emptyEv] 0x28): undefined reference to `IPriorityQueue<int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::size() const'
collect2.exe: error: ld returned 1 exit status

Is there any way I can figure this out? Is such a design even possible? Thank you in advance

CodePudding user response:

Just replace

bool    empty(void) const { return (!size()); }

with

bool    empty(void) const { return (!this->size()); }//note i have added this->

and that will solve your problem.

Here's the rule

the compiler does not look in dependent base classes when looking up nondependent names .

Here's a good article for reading more about this.

  • Related