Having the following example:
/* Signal Container */
template <typename Ret> class Signal;
template <typename Ret, typename... Args>
class Signal< Ret (Args...) >
{
/* Following Implementation... */
};
/* Emitter Type */
template < template <typename Ret, typename... Args> Signal< Ret (Args...) > ... Sig>
class Emitter
{
// using Signals = std::tuple<Sig...>;
/* Following Implementation... */
};
/* Signals */
using Signal_A = Signal<void()>;
using Signal_B = Signal<void(int)>;
using Signal_C = Signal<void(int, float)>;
/* Desired Usage */
class MyType : public Emitter<Signal_A, Signal_B, Signal_C>
{
};
I would like to be able to inherit from an Emitter
type that accepts 1 (0?) or more template parameters of the type Signal
(and only Signal
). Signal
is a templated type and it's definition is different with each type passed to the Emitter
arguments pack.
I tried the current approach on MinGW but I get these error messages and I'm a bit lost:
/* Line: template < template <typename Ret, typename... Args> Signal< Ret (Args...) > ... Sig> */
main.cpp|15|error: expected 'class' before 'Signal'|
/* Line: template < template <typename Ret, typename... Args> Signal< Ret (Args...) > ... Sig> */
main.cpp|15|error: expected '>' before '<' token|
/* Line: class MyType : public Emitter<Signal_A, Signal_B, Signal_C> */
main.cpp|29|error: wrong number of template arguments (3, should be 1)|
/* Linne: class Emitter */
main.cpp|16|error: provided for 'template<template<class Ret, class ... Args> class Signal> class Emitter'|
If anyone could clarify this or provide a working solution I'd be grateful.
Available compilers: MinGW GCC 4.9.2 (also 5.1.0)
You can't do what you want in C++11 or C++14 in an easy way. Concepts might give us something, but for now your template arguments must be either a type, a class template, or a value. In your case, you want a pack of Signals which can only be specified as:
template <typename... Sigs>
class Emitter;
Within the class, you can then use static_assert
to verify that they're all Signal
s:
static_assert(all_true<is_signal<Sigs>::value...>::value, "Emitter must use only Signals");
You'll have to write a type trait for is_signal
, and provide a metafunction for all_true
. One example of the latter can be found here