我正在构建特征类型(类似于 std::type_identity)来表示不同风格的模板模板。混合类型可变参数值模板是一种特殊情况,我只能想到通过嵌套结构体来实现,如下所示。
clang 接受这一点,但 gcc 不接受。
template <typename ... Ts>
struct variadic_value_metatemplate_builder
{
template <template <Ts ... tt_Vs> typename TT>
struct build
{
template <Ts ... Vs>
using type = TT<Vs ...>;
};
};
gcc 的错误是:
<source>:8:39: error: expansion pattern 'tt_Vs' contains no parameter packs [-Wtemplate-body]
8 | using type = TT<Vs ...>;
谁是对的?
gcc 的错误表述似乎Vs ...
不正确,但我猜测这与和Ts ...
的大小要求相同有关,导致它们Vs ...
不能自由可变。但据我所知,它们仍然都是参数包。
编辑:旁白:这为什么有用?
实际上,创建一个实际的用例(针对这种特定风格的模板模板)非常困难,但这是我的快速尝试(非常难以置信,不是很好)。
您正在为一组模板化图形操作编写测试例程。有些是 的形式 <int DIMENSION>
,有些是 的形式<int DIMENSION, bool UNDO>
,等等……您需要为所有 的形式编写一个通用的测试例程,该例程接受一个 形式参数、一组匹配的图形操作以及一组针对这些参数的 constexpr 测试值。然后,您可以执行以下操作:
generic_graphics_test<metabuilder_DIMENSION_UNDO, variadic_auto_constants<2, false>, variadic_auto_constants<3, true>, [etc...]>::test<gfx_translate, gfx_scale, [etc...]>()
;
以某种方式gfx_translate
测试和的2D 和 3D 可撤消种类gfx_scale
。(其中test()
将(上述)的实例build
作为模板参数,这里表示(原始的、未解析的)翻译和缩放模板操作(作为函子或类似的东西))。
(...这就像元嵌套级别 4 或类似的东西:)
((我希望其中至少有 17% 是半可理解的 :))
不幸的是,目前还没有一个通用的“可能是可变类型或值的模板参数”关键字(虽然很好,但可能很难编写编译器代码),它允许每种可能的模板风格都由一个特征模板来表示。