0

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

模板<int I>
结构 X {};

模板<int I>
结构 Y {};

模板<int I>
结构 XX: X<I> {};

模板<int I>
结构 YY: Y<I> {};

模板<template<int> 类 TP>
结构特征;

模板<>
结构特征<X> {
    模板<int I>
    使用 Tpl=XX<I>;
};

模板<>
结构特征<Y> {
    模板<int I>
    使用 Tpl=YY<I>;
};

模板<template<int> 类 TP>
结构 Z {};

模板<template<int> 类 TP>
结构 W: Z<traits<TP>::Tpl> {};

int main() {
 
  Z<特征<X>::Tpl> zx;
  Z<traits<Y>::Tpl> zy;
  W<X> wx;
  W<Y>

  返回 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相同的模板模板参数,但将它们分派给内部类,并通过派生它们来修改它们的行为。ZXYXXYYXY

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

非常感谢!

4

1 回答 1

2

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

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

Afaik,对此没有任何改变,我可能是某些编译器/已经对此更加松懈,让您在没有它的情况下逃脱。需要它的原因与typename类型需要它的原因类似:可能会特化traitswhereTpl不是模板,因此您需要告诉编译器它确实是模板。

于 2020-06-23T12:56:41.320 回答