【问题标题】:Unwrapping variadic template structs展开可变参数模板结构
【发布时间】:2019-03-23 18:14:32
【问题描述】:

我正在尝试创建一个 variant 结构,即包含这么多类型之一的结构。到目前为止,这是我的尝试:

template <typename Type, typename... Rest> struct OneOf {
    union {
        Type value;
        OneOf<Rest...> rest;
    };
};

template <typename Type> struct OneOf {
    Type value;
};

遗憾的是,这无法编译。当我尝试实例化它时,我得到:

one_of.h:34:33: 错误:用 1 个模板参数模板重新声明 结构 OneOf {

有没有办法用结构终止自引用递归?

【问题讨论】:

  • FWIW,您正在尝试制作一个变体。变体可以是一组类型中的一个。任何类型都是无限的。

标签: c++ c++11 variadic-templates template-meta-programming template-specialization


【解决方案1】:

怎么样

template <typename...>
struct OneOf;

template <typename Type, typename... Rest>
struct OneOf<Type, Rest...> {
    union {
        Type value;
        OneOf<Rest...> rest;
    };
};

template <>
struct OneOf<> {
};

?

还有

template <typename, typename...>
struct OneOf;

template <typename T0, typename T1, typename ... Ts>
struct OneOf<T0, T1, Ts...> {
    union {
        T0 value;
        OneOf<T1, Rest...> rest;
    };
};

template <typename T0>
struct OneOf<T0> {
    T0 value;
};

?

【讨论】:

    【解决方案2】:

    我假设您正在尝试编写专业化。

    这是语法:

    template <typename Type> struct OneOf<Type> {
    //                                   ^~~~~~
        Type value;
    };
    

    【讨论】:

    【解决方案3】:

    您必须首先声明主模板,然后声明任何特化(完整或部分)。主模板确定模板参数的数量和种类。当需要实例化模板时,如果完全匹配则使用完全特化,如果匹配则使用最佳匹配部分特化,否则将实例化主模板。

    如果您希望 OneOf 成为一个接受任意数量的类型模板参数(0 或更多)的模板,那么您应该相应地声明主模板:

    template <class... T> struct OneOf;
    

    然后你需要两个特化:一个用于递归的基本情况,可以看作是空包:

    template <>
    struct OneOf<> {};
    

    一个用于递归情况,至少有一个模板参数:

    template <typename Type, typename... Rest> struct OneOf<Type, Rest...> {
        union {
            Type value;
            OneOf<Rest...> rest;
        };
    };
    

    请注意,完全特化和部分特化都需要在模板名称之后有一个模板参数列表。如果你忽略它,编译器会认为你在重新声明主模板,这会导致你看到的错误。

    【讨论】:

    • 我实际上对我写的表单很好(其中零类型是不可接受的)。否则,这绝对是最完整的答案。
    • @ShacharShemesh 足够公平---然后您可以声明主模板,使其采用 1 种或更多类型,基本案例采用 1 种类型,递归案例采用 2 种或更多类型.那样会更冗长。
    猜你喜欢
    • 2012-04-09
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2019-08-04
    • 2014-04-12
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    相关资源
    最近更新 更多