how to define a template class inherit from template class ?
I want to wrap std::queue and std::priority_queue to a base class. In my case is LooperQueue.
I use StdQueue in this way auto queue = new StdQueue<LooperMessage *>().
my class define compiler complain
error log:
  In file included from /Users/rqg/ASProjects/PboTest/muses/src/main/cpp/Painter.cpp:10:
  /Users/rqg/ASProjects/PboTest/muses/src/main/cpp/util/StdQueue.h:14:5: error: unknown type name 'size_type'; did you mean 'size_t'?
      size_type size() override;
      ^~~~~~~~~
      size_t
  /Users/rqg/Library/Android/sdk/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/lib64/clang/5.0.300080/include/stddef.h:62:23: note: 'size_t' declared here
  typedef __SIZE_TYPE__ size_t;
                        ^
  In file included from /Users/rqg/ASProjects/PboTest/muses/src/main/cpp/Painter.cpp:10:
  /Users/rqg/ASProjects/PboTest/muses/src/main/cpp/util/StdQueue.h:16:5: error: unknown type name 'reference'
      reference front() override;
      ^
  /Users/rqg/ASProjects/PboTest/muses/src/main/cpp/util/StdQueue.h:20:21: error: unknown type name 'value_type'; did you mean 'ARect::value_type'?
      void push(const value_type &x) override;
                      ^~~~~~~~~~
                      ARect::value_type
  /Users/rqg/Library/Android/sdk/ndk-bundle/sysroot/usr/include/android/rect.h:44:21: note: 'ARect::value_type' declared here
      typedef int32_t value_type;
code:
#ifndef PBOTEST_LOOPERQUEUE_H
#define PBOTEST_LOOPERQUEUE_H
#include <queue>
#include <cstdlib>
template<typename Tp, typename Sequence = std::deque<Tp> >
class LooperQueue {
  public:
    typedef typename Sequence::value_type                value_type;
    typedef typename Sequence::reference                 reference;
    typedef typename Sequence::const_reference           const_reference;
    typedef typename Sequence::size_type                 size_type;
    typedef          Sequence                            container_type;
    virtual size_type size()  = 0;
    virtual reference front() = 0;
    virtual void pop()= 0;
    virtual void push(const value_type &x) = 0;
};
#endif //PBOTEST_LOOPERQUEUE_H
#ifndef PBOTEST_STDQUEUE_H
#define PBOTEST_STDQUEUE_H
#include "LooperQueue.h"
template<typename Tp, typename Sequence = std::deque<Tp> >
class StdQueue : public LooperQueue<Tp, Sequence> {
  public:
    size_type size() override;
    reference front() override;
    void pop() override;
    void push(const value_type &x) override;
    
  private:
    std::queue<Tp, Sequence> mQueue;
};
#endif //PBOTEST_STDQUEUE_H
                I'm going to use a simpler example that gives you the same error, consider a base with just one alias defined and a subclass that tries to use it:
template <typename T>
class Base {
 public:
  using value_type = T;
};
template <typename T>
class Derived : public Base<T> {
  value_type func();  // error
};
Because of the crazy nature of templates, the compiler can't know what value_type is at this point.  You have to tell it that it comes from the Base class either by qualifying it:
template <typename T>
class Derived : public Base<T> {
  typename Base<T>::value_type func();
};
or telling the compiler with a using declaration that you are intending to use a base class type alias
template <typename T>
class Derived : public Base<T> {
  using typename Base<T>::value_type;
  value_type func();
};
The compiler can't actually know that Base<T> contains a value_type until it knows what T is and instantiates the template. Why can't it just look at the Base template? -- such a thing would be theoretically possible, but it doesn't know what specializations will be available.  If somewhere else you had
template<>
class Base<int> {};
Then Derived<int> would have to look for value_type elsewhere in its scope, and that's what it does in your original code. It tries to find a value_type and fails. This behavior can lead to some surprising results:
using value_type = char;
template <typename T>
class Derived : public Base<T> {
  value_type func(); // this is the global value_type = char, always
};
For a more ground-up explanation on related topics you can read my medium post
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With