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.