代码之家  ›  专栏  ›  技术社区  ›  sylvain

可变模板和SFINAE

  •  2
  • sylvain  · 技术社区  · 8 年前

    我在玩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
    
    3 回复  |  直到 8 年前
        1
  •  6
  •   odinthenerd    8 年前
    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> _类型和状态只是类型通配符,您只需要 template <typename, typename> class F 如果需要将模板参数与通配符匹配,则使用模板模板参数语法。在这种情况下,您将该模板与名为Input的已知模板进行匹配

        2
  •  5
  •   TartanLlama    8 年前

    你对最后一个案例的部分特化是不正确的。你需要推断 _Type _State ,没有模板参数。

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

    在原始代码中,模板模板参数内的名称不会为该部分专门化引入模板参数。

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

        3
  •  0
  •   oisyn    8 年前

    除了其他人已经提供的完美答案外,我可以问一下你的预期结果是什么样的吗 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<*,*> .