Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Templates with multiple constraints

In C# I am used to specify multiple constraints in a generic method or type as shown right here:
How do I specify multiple generic type constraints on a single method?

Today I started with C++ for the first time and I am unable to find anything useful when googling for template multiple constraints.
It almost looks like this is not possible and everyone knows it, and thus no questions asked.

I know that in C# generics are much stronger validated by the compiler than in C++, and that is why it feels wrong to me not to be able to constrain my types to multiples super-types.

like image 290
Noel Widmer Avatar asked Dec 20 '22 03:12

Noel Widmer


2 Answers

This is possible in C++ today, but with quite complex syntax. In the next major C++ release we will most likely get a version of concepts, which make this much easier.

In C++14, the C# example you posted might look like this:

template <class TResponse, class TRequest,
          std::enable_if_t<std::is_base_of<MyClass, TRequest>::value &&
                           std::is_base_of<MyOtherClass, TResponse>::value>* = nullptr>
TResponse Call(TRequest request);
like image 145
TartanLlama Avatar answered Dec 22 '22 11:12

TartanLlama


you usually make constraints on C++ template with std::enable_if

here is the trick - if your template looks like this:

template <class T>
<return type> <function name> (args...)

you take the return type and corporate it with enable_if like this :

template <class T>
typename std::enable_if<XXX,<return type>>::type
 <function name> (args...)

here, XXX represents your compile-time condition.

for example: let add(T1 t1 , T2 t2) be compiled for only objects that inherit from Addable :

template <class T1, class T2>
 typename std::enable_if<
   std::is_base_of<Addable,T1>::value && std::is_base_of<Addable,T2>::value
 decltype(T1()+T2())>::type
 add (T1 t1, T2 t2){
    return t1+t2;
 }
like image 31
David Haim Avatar answered Dec 22 '22 09:12

David Haim