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> {
...
?
Related
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>);
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> > {};
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 {};
I want to do something like this:
template<class T>
class BaseSubscriber {};
template<class T>
class BasePublisher
{
// not working : invalid use of template-name 'BaseSubscriber' without an argument list
typedef BaseSubscriber SubscriberType;
// compiling
typedef BaseSubscriber<T> SubscriberTypeT;
};
template< template<class T> class Subscriber, class Data >
class ClassA:
public Subscriber<Data>
{
};
template< template<class T> class Publisher, class Data >
class ClassB:
public Publisher<Data>
{
// Ok, but I want that the type "BaseSubscriber" depends on the template parameter Publisher
void method1(ClassA<BaseSubscriber, Data>&);
// I want something like that. But how to define SubscriberType ?
void method2(ClassA<Publisher<Data>::SubscriberType, Data>&);
// or (SubscriberType only depends on the Publisher, nor on the Data)
void method2(ClassA<Publisher::SubscriberType, Data>&);
// Error : template argument is invalid
void method3(ClassA<Publisher::SubscriberTypeT, Data>&);
};
Is it possible to define some SubscriberType that I can use for classA template parameter? Or is there any work around?
If possible I'd like to keep the classA prototype. I don't want to change it in
template<class TSubscriber > classA {};
And I can't use C++11.
Thanks a lot for your answers.
It is a bit confusing what you mean when you say:
// I want something like that. But how to define SubscriberType ?
void method2(ClassA<Publisher::SubscriberType>);
As Publisher is a template yet you're not passing it any arguments.
Anyway, here are some options:
In C++11 you can use template aliases:
template<class T>
class BasePublisher
{
template<typename U>
using SubscriberType = BaseSubscriber<U>;
};
You can also use nested classes:
template<class T>
class BaseSubscriber {};
template<class T>
class BasePublisher
{
template<class U>
class BaseSubscriber {};
};
Or change ClassA to use a type member:
template<class T>
class BasePublisher
{
template<class U>
struct SubscriberType {
typedef BaseSubscriber<U> type;
};
};
template< template<class T> class SubscriberT >
class ClassA {
typedef typename SubscriberT::type Subscriber;
};
Or sometimes inheritance works if you don't need an alias:
template<class T>
class BasePublisher
{
template<class U>
struct SubscriberType : BaseSubscriber<U> {};
};
Template aliases are not allowed in C++03 although they are in C++11.
Is your goal is to be able to do:
typename BaseSubscriber<A>::SubscriberType<B>
in C++03 you should use a nested class thus:
template< typename T > struct BasePublisher
{
template< typename U > struct Subscriber
{
typedef BaseSubcriber<U> type;
};
};
and now you can possibly do typename BasePublisher::Subscriber::type;
In C++11 the syntax would be:
template < typename T > struct BasePublisher
{
template< typename U > using SubscriberType = BaseSubscriber<U>;
};
there are not many compilers that support that yet.
although as you can't do typename typename it might need another typedef in between.
If I get it correctly you want ClassA to get an instantiation of BaseSubscriber, for example BaseSubscriber<my_tag> and ClassB on an instantiation of BasePublisher. is it correct?
If your answer is yes, then why you declare template argument of ClassA and ClassB as template, you don't want to do something with it in ClassA or ClassB, so it should be a class not a templated class:
template<class T>
class BasePublisher
{
// compiling
typedef BaseSubscriber<T> SubscriberTypeT;
};
template< class SubscriberT > class ClassA : SubscriberT {};
template< class PublisherT >
class ClassB : PublisherT {
void method1( ClassA<typename PublisherT::SubscriberTypeT> );
};
I have the following base class :
template <template<class Type> class T2>
class FundamentalClass {
typename T2<double> *_compose1;
typename T2<int> *_compose2;
protected:
FundamentalClass(); // Insert constructors here.
template<class Strategy>
T2<typename Strategy::Type> *Construct(void);
public:
template <class Strategy>
T2<typename Strategy::Type> *GetComposedObject(void);
};
with
template< template<class Type> class T2>
template<>
T2<double> *FundamentalClass<T2<double> >::GetComposedObject<DoubleStrategy>(void) {
if( NULL == _compose1) {
_compose1 = Construct<DoubleStrategy>(void);
}
return _compose1;
}
And other specializations for each composed object.
But, i need construct to be implemented by the derived class. Without templates, Construct whould be virtual. How can i achieve this goal ?
You can do this with compile-time polymorphism, via the Curiously Recurring Template Pattern (CRTP):
template <template<class Type> class T2, class Derived>
class FundamentalClass {
...
template<class Strategy>
T2<typename Strategy::Type> *Construct() {
return static_cast<Derived *>(this)->DoConstruct<Strategy>();
}
And in Derived, write:
template <template<class Type> class T2>
class Derived: public FundamentalClass<T2, Derived<T2> >
{
public:
template<class Strategy>
T2<typename Strategy::Type> *DoConstruct() {
...
}