rahman
rahman

Reputation: 4948

can't invoke Base templated class's constructor from the derived class

I have a hierarchy like this:

#include <boost/shared_ptr.hpp>
//base cache
template <typename KEY, typename VAL>  class Cache;
//derived from base to implement LRU
template <typename KEY, typename VAL>  class LRU_Cache :public Cache<KEY,VAL>{};
//specialize the above class in order to accept shared_ptr only
template <typename K, typename VAL>
class LRU_Cache<K, boost::shared_ptr<VAL> >{
public:
    LRU_Cache(size_t capacity)
    {
        assert(capacity != 0);
    }
//....
};

//so far  so good

//extend the LRU
template<typename K, typename V>
class Extended_LRU_Cache : public LRU_Cache<K,V >
{
public:
    Extended_LRU_Cache(size_t capacity)
    :LRU_Cache(capacity)// <-- this is where the error comes from
    {
        assert(capacity != 0);
    }
};

and the error says:

template-1.cpp: In constructor ‘Extended_LRU_Cache<K, V>::Extended_LRU_Cache(size_t)’:
template-1.cpp:18:38: error: class ‘Extended_LRU_Cache<K, V>’ does not have any field named ‘LRU_Cache’
  Extended_LRU_Cache(size_t capacity):LRU_Cache(capacity)

can you please help me out find the missing part?

thanks

Upvotes: 2

Views: 69

Answers (2)

cdhowie
cdhowie

Reputation: 168958

You need to specify the template parameters of the base type:

Extended_LRU_Cache(size_t capacity)
:LRU_Cache<K, V>(capacity)
{
    assert(capacity != 0);
}

Because you don't provide them, the compiler does not make the connection that you are trying to call a base constructor because you don't derive from a type called LRU_Cache, and so it looks for a field with the name LRU_Cache to initialize instead. It should be obvious now why you receive this pariticular error message.

The template parameters are required because you can derive from the same templated type twice with different template arguments, and then the base constructor call would be ambiguous:

template <typename T>
class Base
{
public:
    Base() { }
};

template <typename T, typename U>
class Derived : Base<T>, Base<U>
{
public:
    // error: class ‘Derived<T, U>’ does not have any field named ‘Base’
    // Derived() : Base() { }
    //             ^
    // Which Base constructor are we calling here?

    // But this works:
    Derived() : Base<T>(), Base<U>() { }
};

Upvotes: 2

Some programmer dude
Some programmer dude

Reputation: 409136

When calling the base constructor, you need the full definition of the parent (i.e. with template arguments):

Extended_LRU_Cache(size_t capacity)
:LRU_Cache<K,V>(capacity)
{
    assert(capacity != 0);
}

Upvotes: 2

Related Questions