【问题标题】:What's the syntax to partially specialize a parmeter pack argument for void type?将参数包参数部分专门化为 void 类型的语法是什么?
【发布时间】:2018-11-22 08:02:06
【问题描述】:

我找不到让它工作的方法。甚至可能吗?我不明白为什么不会。

template <auto id, typename FirstField, typename... OtherFields>
struct FieldTypeById {
    using Type = int;
};

template <auto id>
struct FieldTypeById<id, void> {
    using Type = void;
};


int main()
{
   using t1 = FieldTypeById<0, int>::Type;
   using t2 = FieldTypeById<1>::Type;

    return 0;
}

https://godbolt.org/z/AggnDq

【问题讨论】:

    标签: c++ templates c++17 template-specialization


    【解决方案1】:

    您的示例中的问题不在于专业化,这很好。问题是FieldTypeById&lt;1&gt; 无法推断出FirstField 的类型。您可以通过简单地向主模板添加默认值来修改它:

    template <auto id, typename FirstField = void, typename... OtherFields>
    struct FieldTypeById {
        using Type = int;
    };
    

    现在所有参数都是显式给出的,取自默认值,或推导(作为一个空包)。知道所有参数后,就可以使用这些参数的特化。

    See it live

    【讨论】:

    • 嗯。如果“主”模板有FirstField = void,这意味着它可以直接与FieldTypeById&lt;1&gt;匹配,那么特化是否会被实例化?我现在可以看到,我可以只使用一个包含= voidstd::conditional 的模板来实现相同的目标,但我仍然想知道它是否可以通过专业化来完成。
    • @VioletGiraffe - 当模板的参数匹配时,特化被实例化。但是默认参数只能出现在主模板上,因为这是模式匹配的开始(通俗地说)。
    • 我是否正确理解为了特化一个模板,首先必须确保所需的特化实例可以与主模板匹配?
    • @StoryTeller :是不是因为当我们在模板中传递参数列表时没有类型推导(与函数模板不同)?我想过!!
    • 谢谢,这是我在多年使用 C++ 的过程中不知何故错过的重要知识!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多