模板模板参数和模板别名:编译器错误?

Template template parameter and template alias: compiler bug?

本文关键字:错误 编译器 别名 参数      更新时间:2023-10-16

我对以下代表性示例代码有问题:

模板结构 Y {}; 模板结构 YY: Y{}; 模板<模板>类TP> 结构性状; 模板<> 结构特征{ 模板使用 Tpl=YY; }; 模板<模板>类TP> 结构体 Z {}; 模板<模板>类TP> struct W: Z::Tpl> {}; int main(( {  Z::Tpl> zx; Z::Tpl> zy; Wwx; Wwy; 返回 1; }

这段代码在 icc-19.0.0 中编译得很好(并且似乎使用 msvc-19.24 编译(,但无法使用 gcc-10.1、clang-10.0.0 和 icc-18.0.0 编译。

对于 gcc-10.1,错误消息为:

<source>:32:28: error: type/value mismatch at argument 1 in template parameter list for 'template<template<int <anonymous> > class TP> struct Z'
32 | struct W: Z<traits<TP>::Tpl> {};
|                            ^
<source>:32:28: note:   expected a class template, got 'traits<TP>::Tpl'

上下文:我有一个模板类Z它有一个模板模板参数。我想从中派生一个类,W,对于最终用户来说,它接受与Z相同的模板模板参数(XY(,但将它们调度到内部类XXYY,通过从它们派生来修改XY的行为。

这个问题是编译器错误吗?如果是,是否有某种解决方法?

非常感谢!

你需要告诉编译器Tpl是一个模板:

template<template<int> class TP>
struct W: Z<traits<TP>::template Tpl> {};
// ^^      

Afaik,对此没有任何改变,我可能是一些编译器对它更加宽松,让你在没有它的情况下逃脱。 需要它的原因类似于为什么类型需要typename:可能存在traits的专用化,其中Tpl不是模板,因此您需要告诉编译器它确实是一个模板。