Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic template template and SFINAE

I'm toying with SFINAE and I try to check my Inputs is made of Input of various types. The error provided by clang doesn't help much. Do you have any idea ?

Thanks

struct IsFree
{
};

template <typename _Type, typename _State>
struct Input
{
};

template <typename... _Inputs>
struct Inputs
{
};

template <template <typename _Type, typename _State> class, typename... _Inputs>
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
{
};

Somewhere else :

auto temp = Inputs<Input<float, IsFree>, Input<float, IsFree>> {};

I get using clang-5.0 and -std=c++17 :

13 : <source>:13:21: error: use of undeclared identifier '_Type'
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
                    ^
13 : <source>:13:35: error: expected a type
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
                                  ^
2 errors generated.
Compiler exited with result code 1
like image 630
sylvain Avatar asked Dec 11 '25 14:12

sylvain


2 Answers

template <template <typename _Type, typename _State> class, typename... _Inputs>
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
{
};

needs to be

template <typename _Type, typename _State, typename... _Inputs>
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
{
};

in the pattern Input<_Type, _State> _Type and _State are just type wildcards, you only need the template <typename, typename> class F template template parameter syntax if you need to match a template template parameter with a wild card. In this case you are matching the template with a known template named Input

like image 166
odinthenerd Avatar answered Dec 14 '25 04:12

odinthenerd


Your partial specialization for the last case is not correct. You need to deduce _Type and _State, not have a template template parameter.

template <class _Type, class _State, typename... _Inputs>
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
{
};

In your original code, the names inside the template template parameter do not introduce template parameters for that partial specialization.

Also note that names beginning with an underscore and capital letter are reserved to the implementation, so you should not use them in your own code.

like image 41
TartanLlama Avatar answered Dec 14 '25 04:12

TartanLlama