变异模板模板和SFINAE

时间:2017-11-22 11:53:03

标签: c++ c++11 templates variadic-templates

我正在玩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}}

3 个答案:

答案 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<*,*>列表的参数来实例化模板。