2

I'm trying to write a template class that defines its template based on the template implementation of a interface. To clarify my problem, here a example.

template<typename T>
class A{
    virtual T getValue() = 0;
}

class B : public A<int>{
    //does some things and implements getValue
}

//template definition
//T should become int by passing class B
class C{
    A* aPointer;
    T previousValue;
} 

I've tried template template (not a typing error) syntax, explained really nice in this post. What are some uses of template template parameters in C++?. But because the type of A is determent in the definition of B it doesn't work.

How should i go about and create a template that determines T.

Community
  • 1
  • 1
sqrtroot
  • 167
  • 2
  • 9

3 Answers3

3

You can't determine the type of T directly from B, but you can from its interface. The best way of handling this would be to add a typedef of T to A.

template<typename T>
class A{
    virtual T getValue() = 0;
public:
    typedef T ValueType;
}

class B : public A<int>{
    //does some things and implements getValue
}

template<class T>
class C {
    A<typename T::ValueType>* aPointer;
    typename T::ValueType previousValue;
} 
user1937198
  • 4,987
  • 4
  • 20
  • 31
0

Define a named type alias in class interfaces.

The standard library also does this.

template<typename T>
class A{
  public:
    using value_type = T;
    virtual value_type getValue() = 0;
};

class B : public A<int>{
public:
  using A<int>::value_type;
    //does some things and implements getValue
  value_type getValue() override { return 0; }
};

//template definition
//T should become int by passing class B
template<class Derived>
class C{
public:
  using value_type = typename Derived::value_type;
    A<value_type>* aPointer;
    value_type previousValue;
};

int main()
{
  C<B> c;

  auto x = c.aPointer->getValue();

}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
0

You can use a support function of which you don't even have to give a definition.
It follows a minimal, working example:

#include<type_traits>
#include<utility>

template<typename T>
class A{};

class B : public A<int>{};

template<typename T>
T a_type(const A<T> &);

template<typename T>
class C {
public:
    using type = decltype(a_type(std::declval<T>()));
};

int main() {
    static_assert(std::is_same<C<B>::type, int>::value, "!");
}

The good part of this approach is that you don't have to modify neither A nor B.

skypjack
  • 49,335
  • 19
  • 95
  • 187