展开可变参数模板结构

Unwrapping variadic template structs

本文关键字:结构 参数 变参      更新时间:2023-10-16

>我正在尝试创建一个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 {

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

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

如果您希望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;
};
};

请注意,完全专用化和部分专用化都需要在模板名称后使用模板参数列表。如果省略此项,编译器会认为您正在重新声明主模板,从而导致您看到的错误。

我假设你正在尝试编写一个专业化。

这是语法:

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

怎么样

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

O 也

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;
};