当前位置: 首页 > 知识库问答 >
问题:

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

祝宏放
2023-03-14

我遇到以下代表性示例代码的问题:

template<int I>
struct X {};

template<int I>
struct Y {};

template<int I>
struct XX: X<I> {};

template<int I>
struct YY: Y<I> {};

template<template<int> class TP>
struct traits;

template<>
struct traits<X> {
    template<int I>
    using Tpl=XX<I>;
};

template<>
struct traits<Y> {
    template<int I>
    using Tpl=YY<I>;
};

template<template<int> class TP>
struct Z {};

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

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

  return 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,它有一个template模板参数。 我想从中派生一个类w,对于最终用户来说,它接受与z(xy)相同的模板模板参数,但将它们分派给内部类xxyy,后者通过派生它们来修改xy的行为。

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

非常感谢!

共有1个答案

索嘉胜
2023-03-14

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

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

Afaik,没有任何改变,我可能是一些编译器是/已经对它更松懈,让你离开没有它。 需要它的原因与类型需要typeName的原因类似:可能存在traits的专门化,其中tpl不是模板,因此您需要告诉编译器它确实是模板。

 类似资料:
  • 另一个有用的可能示例:(伪代码)

  • 考虑下面粘贴的代码。我定义了一个非常简单的类,编译器为其生成一个隐式推导指南,这样就可以在没有显式模板参数的情况下构造它。但是,模板参数推导不适用于从仅直接转发到目标类的简单别名模板构造对象: 正如您从上面的代码注释中看到的,g给了我一个关于使用别名模板而没有模板参数的错误。我希望在这样的例子中,模板参数推导会被转发。 所以,我的问题是:这是通过明示设计目前的措辞来对班级模板的论点进行演绎的建议吗

  • 主要内容:编译JRXML文件,预览Jasper文件我们在上一章中生成了 JasperReport 模板(JRXML 文件)。该文件不能直接用于生成报表。它必须编译为 JasperReport 的原生二进制格式,称为Jasper文件。在编译时,我们将 JasperDesign 对象转换为 JasperReport 对象。 接口net.sf.jasperreports.engine.design.JRCompiler在编译过程中起着核心作用。该接口有

  • 你可能有兴趣知道,Vue 的模板实际是编译成了 render 函数。这是一个实现细节,通常不需要关心,但如果你想看看模板的功能是怎样被编译的,你会发现会非常有趣。下面是一个使用Vue.compile来实时编译模板字符串的简单 demo: <div> <header> <h1>I'm a template!</h1> </header> <p v-if="message">

  • 尽管 PHP 不断升级为成熟的、面向对象的语言,但它作为模板语言 没有改善多少。编译型模板,比如 Twig、Brainy 或 Smarty,提供了模板专用的新语法,填补了这片空白。从自动转义到继承以及简化控制结构,编译模板设计地更容易编写,可读性更高,同时使用上也更加的安全。编译型模板甚至可以在不同的语言中使用,Mustache 就是一个很好的例子。由于这些模板需要编译,在性能上会带来一些轻微的影

  • 当我编译时,我得到了这些错误:

  • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

  • 我试图在类型s. t上专门化一个类。它忽略了给定类型的恒定性。在这种情况下,该类型是一个模板模板参数: 上面的代码在GCC 4.8.4和clang 5.0(with-std=c 11)中都抱怨bar在与匹配FOFType模板参数化的类一起使用时未定义。即使我删除了sfinae参数,仍然无法找到特化。 这个问题的一个例子可以在这里找到:https://godbolt.org/g/Cjci9C.在上面