# C++11 variadic template + inheritance

I would like to write an abstraction of linear superpositions using variadic templates. To do that, I would like to define a base type that exhibits a certain form of operator() like so

template <typename Result, typename... Parameters> class Superposable { public: typedef Result result_t; void operator()(Result& result, const Parameters&...) const = 0; };

then inherit from it for the current problem, for instance like so

class MyField : public Superposable<double, double, double> { public: void operator()(double& result, const double& p1, const double& p2) const { result = p1 + p2; } };

And I would then like to write an abstract base class that can form linear superpositions and gets the Superposable-derived class as a template parameter to determine the call signature of operator(). I would like to have something like

template<typename S> // where S must be inherited from Superposable class Superposition { private: std::vector< std::shared_ptr<S> > elements; public: // This is the problem. How do I do this? void operator()(S::result_t& result, const S::Parameters&... parameters) const { for(auto p : elements){ S::result_t r; p->operator()(r, parameters); result += r; } } };

Here are my questions:

- How do I read out the type information from the Superposable-derived class to define my operator() in Superposition?
- Also, is there a recommended way to enforce that Superposition can only be called with a Superposable-derived class as an argument?
- An even nicer solution would of course be to write a Superposition class that does not require MyField to be derived from a base class, but directly parses MyField's operator(). Can I do this somehow?

Thanks for your help!

## Answers

First, a solution to your problem directly.

Some metaprogramming boilerplate:

template<class...>struct types{using type=types;};

A hana-style function that extracts the types of an argument, optionally taking a template from which to do the extraction based on:

template<template<class...>class Z, class...Args> constexpr types<Args...> extract_args( Z<Args...> const& ) { return {}; }

An alias that wraps the above in a decltype for ease of use:

template<template<class...>class Z, class T> using extract_args_from = decltype( extract_args<Z>( std::declval<T>() ) );

The primary template of Superposition is left empty, with a default argument that extracts the type arguments of Superposable:

template<class S, class Args=extract_args_from<Superposable, S>> class Superposition;

then a specialization that gets the Result and Parameters types of the (possibly base class of) S's Superposable:

template<class S, class Result, class...Parameters> class Superposition< S, types<Result, Parameters...>> {

live example. Btw, you missed a virtual.

Note that I don't approve of your design -- the result should be the return value (naturally), making () virtual seems like a bad idea (I'd use CRTP instead, and type-erase if I really need to hide the particular implementation).

You can remove the body of Superposable and it works as-is:

public: typedef Result result_t; void operator()(Result& result, const Parameters&...) const = 0;

which I'd recommend at the least.

The next step is to get rid of inheritance and deducing Parameters at all:

class MyField { public: double operator()(const double& p1, const double& p2) const { return p1 + p2; } }; template<typename S> // where S must be inherited from Superposable class Superposition { private: std::vector< std::shared_ptr<S> > elements; public: template<class...Parameters, class R=std::result_of_t<S&(Parameters const&...)> > R operator()(const Parameters&... parameters) const { R ret = {}; for(auto p : elements){ ret += (*p)(parameters...); } return ret; } };

which has all the flaws of perfect forwarding, but all the advantages as well.

std::result_of_t<?> is C++14, but replace it with typename std::result_of<?>::type in C++11 as a drop-in.