Inheritance with abstract template class - c++

Lets say I have an template class and i would like to derive it from an abstract class
I wrote the abstract class declaration as follows:
template<typename T, class Derived>
class AbstractClass{
};
How do I derive my template class correctly?
At the moment it looks like:
template <typename T>
class TemplateClass{};

I see you are playing with CRTP? The proper way is following:
template <typename T>
class TemplateClass : public AbstractClass<T, TemplateClass<T> > {};

Related

Check if class is derived from templated class

I'm trying to check if a class that I'm templating is inheriting from another templated class, but I can't find the correct way to do it.
Right now I have the following:
#include <iostream>
template <typename MemberType, typename InterfaceType>
class Combination : public InterfaceType
{
public:
Combination();
virtual ~Combination();
private:
MemberType* pointer;
};
class MyInterface {};
class MyMember {};
class MyCombination : public Combination<MyMember, MyInterface>
{
};
int main()
{
static_assert(std::is_base_of_v<Combination<MyMember, MyInterface>, MyCombination>);
std::cout << "hello";
}
Which is working fine, but in the place this template is placed, I don't have access to the template parameters definitions, and this should be quite generic. What I'd like is to test for the MyCombination class to inherit from a generic Combination without taking into account the template arguments, something like this:
static_assert(std::is_base_of_v<Combination, MyCombination>);
or
static_assert(std::is_base_of_v<Combination<whatever, whatever>, MyCombination>);
Would you know how to check for this?
In this case I can't use boost libraries or other external libraries.
Thanks!
EDIT: I don't have access to modify the Combination class, and what I can change is the assert and the My* classes.
This can easily be done with the C++20 concepts. Note that it requires a derived class to have exactly one public instantiated base class.
template <typename, typename InterfaceType>
class Combination : public InterfaceType {};
class MyInterface {};
class MyMember {};
class MyCombination : public Combination<MyMember, MyInterface> {};
template<class Derived, template<class...> class Base>
concept derived_from_template = requires (Derived& d) {
[]<typename... Ts>(Base<Ts...>&) {}(d);
};
static_assert(derived_from_template<MyCombination, Combination>);
Demo
The equivalent C++17 alternative would be
#include <type_traits>
template<template<class...> class Base, typename... Ts>
void test(Base<Ts...>&);
template<template<class...> class, class, class = void>
constexpr bool is_template_base_of = false;
template<template<class...> class Base, class Derived>
constexpr bool is_template_base_of<Base, Derived,
std::void_t<decltype(test<Base>(std::declval<Derived&>()))>> = true;
static_assert(is_template_base_of<Combination, MyCombination>);

How to do visible nested-class for container-class in inheritance level?

I have some template class
template <typename T> class Base { };
I trying to inherit Derived class from Base and use Internal class that is nested of Derived as a generic argument of Base.
class Derived : Base<Internal> {
public: class Internal { };
}
But compiler doesn't see Internal in Base.
Is it possible to solve my problem with keeping Internal class as nested of Derived?
And if it is possible - How?
You can! Nope
(similar question)
I don't think that this can work. In order to define the class Derived you need to know the base class ("it must be a complete type") first; to instantiate the template Base into a class you need to have a type. Inner however is only a type "inside" of Derived; it's part of it's definition.
Definition of Derived ---needs---> Base<Derived::Inner>
^ |
|----------needs----------------|
Even an indirection does not help:
template<typename T>
class Base {};
template<template<class> class X, typename T>
struct UseInner : public X<typename T::Inner> {};
class Derived : UseInner<Base, Derived>
{
public: class Inner {};
};
In contrast to this, the CRTP works because there the template parameter can be an incomplete type ("no need to access internals").
Wrapping in a template doesn't work:
template<typename T>
class Base {};
template<template<class>class X>
struct Wrap
{
struct Derived : X<typename Derived::Inner> {
struct Inner {};
};
};
using RealDerived = typename Wrap<Base>::Derived;

Passing alias template to base class of a template it depends on

Consider the following code, that defines an alias template to be passed as an template template parameter:
template<template<class T> class SomeFoo>
class Base {};
template<class T, class Bar>
class Foo {};
class Bar;
template<class T>
using BarFoo = Foo<T, Bar>;
class Bar : public Base<BarFoo> {};
This works as expected. However, if Bar itself is a template, this solution is not possible, as the alias template depends on the concrete instantiation of Bar. Defining the alias template inside of Bar doesn't help either, as it is not yet available when the base class is given. As it seems not to be possible to define the alias template "on the fly" in the parameter list, the only work around I could come up with is to pass Bar to Base and define the alias template there:
template<template<class T, class Derived> class SomeFooTL, class Derived>
class Base
{
template<class T>
using SomeFoo = SomeFooTL<T, Derived>;
};
template<class T, class Bar>
class Foo {};
template<class S>
class Bar : public Base<Foo, Bar<S>> {};
This is, however, very unsatisfying, as there could be (and are) other Foo's that do not depend on anything but T and now are forced to take an unnecessary second template parameter.
Does anyone know a better way to achieve this?
If I understand correctly what you want, you need an helper, and using a not obvious syntax:
template<template<class> class>
class Base {};
template<class, class>
class Foo {};
template <typename> class Bar;
template <typename S> struct UsingHelper {
template <typename T>
using BarFoo = Foo<T, Bar<S>>;
};
template <typename S>
class Bar : public Base<UsingHelper<S>::template BarFoo> {};
template is needed in UsingHelper<S>::template BarFoo as it is a dependent context, and it would be "interpreted" as value instead without. (it is similar to typename my_class<T>::type, but BarFoo is a template, not a type.)
Instead of:
template<template<class T> class SomeFoo>
class Base {};
You might want:
template<class SomeFooT>
class Base {};
And use SomeFooT::type<T> as a template:
struct BarFooT {
template<typename T>
using type = ...;
};
Then you can predeclare struct BarFooT;.

Multiple template types

Is it possible to have multiple template types in C++?
For example;
template<template<typename> class BaseClass>
class MyClass {};
template<class BaseClass>
class MyClass {};
And using it;
// Using the first template (template<typename> class BaseClass)
template<typename SubClass>
class MyFirstSubClass : public MyClass<MyFirstSubClass> {};
// Using the second template (class BaseClass)
class MySecondSubClass : public MyClass<MySecondSubClass> {};
You can't have separate templates with the same name, but you can have a base template and one or more specializations of that class.
template<class BaseClass>
class MyClass
{ };
template<class T, template<typename> class BaseClass>
class MyClass<BaseClass<T>>
{ };
template<>
class MyClass<int>
{ };
No, it's not possible. You'll have to have two different template classes:
template<template<typename> class BaseClass>
class MyClassA {};
template<class BaseClass>
class MyClassB {};

deriving a templated class in c++

I have a templated base class which follows:
template<class scalar_type, template<typename > class functor>
class convex_opt{ ..
};
How to derive a class from this templated class?
template<class scalar_type, template<typename > class functor>
class derived : public convex_opt<scalar_type, functor> {
...
?