我正在玩SFINAE并试图检查我的输入是由各种类型的输入组成的。 clang提供的错误并没有多大帮助。你有什么想法吗?
由于
auto temp = Inputs<Input<float, IsFree>, Input<float, IsFree>> {};
其他地方:
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
我使用clang-5.0和-std = c ++ 17:
{{1}}
答案 0 :(得分:6)
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
模板模板参数语法。在这种情况下,您将模板与名为Input
答案 1 :(得分:5)
您对最后一个案例的部分专业化是不正确的。您需要推断_Type
和_State
,而不是模板模板参数。
template <class _Type, class _State, typename... _Inputs>
struct Inputs<Input<_Type, _State>, _Inputs...> : public Inputs<_Inputs...>
{
};
在原始代码中,模板模板参数中的名称不会为该部分特化引入模板参数。
另请注意,以下划线和大写字母开头的名称将保留给实现,因此您不应在自己的代码中使用它们。
答案 2 :(得分:0)
除了其他人已经提供的完美答案外,请问您的预期结果是什么类型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<*,*>
列表的参数来实例化模板。