Variadic模板模板和Sfinae

Variadic template template and SFINAE

本文关键字:Sfinae Variadic      更新时间:2023-10-16

我正在用Sfinae玩耍,我尝试检查我的输入是由各种类型的输入组成的。Clang提供的错误无济于事。你有任何想法吗?

谢谢

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...>
{
};

其他地方:

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

我使用clang -5.0和-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
template <template <typename _Type, typename _State> class, typename... _Inputs>
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
{
};

需要

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

在模式Input<_Type, _State> _ type和_state中只是键入通配符,如果需要将模板模板参数与通配符匹配,则只需要template <typename, typename> class F模板模板参数语法。在这种情况下,您将模板与已知模板匹配

您对最后情况的部分专业化是不正确的。您需要推断_Type_State,没有模板模板参数。

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

在您的原始代码中,模板模板参数中的名称不引入该部分专业化的模板参数。

还要注意,以下划线和大写字母开头的名称保留给实施,因此您不应在自己的代码中使用它们。

除了其他人已经提供的完美答案之外,我可以问您的预期结果是什么类型的Inputs<Input<float, IsFree>, int, Input<int, IsFree>>?注意中间的流浪int。您是否希望基类递归在第一个非Input<>参数停止,因为在您的示例中是这种情况,或者有一个编译错误?

如果后者,我可能建议将一般Inputs模板定义更改为不完整的类型,然后在零模板参数的情况下专门用于空结构,例如:

// General case, incomplete type
template<class... T>
struct Inputs;
// Special case for zero arguments, empty struct
template<>
struct Inputs<>
{
};

与您对Inputs<Input<*,*>, ...>的专业化一起,这将确保您永远无法使用不是Input<*,*>列表的参数实例化模板。