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

C语言中的递归类模板和隐式实例化错误

米俊晤
2023-03-14

下面的最小可复制示例包含一个模板struct B,其默认参数类型包含lambdaa

template<auto>
struct A{};

template<class = A<[]{ return 1; }>>
struct B : B<> {};

template<auto z>
struct B<A<z>> {};

B<int> x;

GCC同意该示例,但Clang抱怨:

error: implicit instantiation of template 'B<A<{}>>' within its own definition

演示:https://gcc.godbolt.org/z/xzjzo7dE9

哪个编译器在这里?

P. S.如果这样修改B的定义:

template<class>
struct B : B<A<[]{ return 1; }>> {};

然后所有的编译器都会非常高兴,演示:https://gcc.godbolt.org/z/roqnc39eq


共有2个答案

童花蜂
2023-03-14

是的,由于以下原因,原始程序格式不正确:https://timsong-cpp.github.io/cppwp/n4868/temp.res#general-8.4.

可以通过向前移动模板专门化来解决此问题:

template<auto>
struct A{};

template<class = A<[]{ return 1; }>>
struct B;

template<auto z>
struct B<A<z>> {};

template<class>
struct B : B<> {};

B<int> x;

现在克朗和海湾合作委员会都接受了:https://gcc.godbolt.org/z/6TYdvTnMa

翟英达
2023-03-14

哪个编译器在这里?

两者都是,因为B格式不正确;国家发改委。一如既往,[temp.res]/8适用于:

可以在任何实例化之前检查模板的有效性。如果出现以下情况,程序格式不正确,无需诊断:

(8.4)-由于不依赖于模板参数的构造,紧跟其定义的模板的假设实例化将是格式错误的,或

模板是B,此处的“其”定义说明了主模板。如果我们要实例化B

顺便说一句,这整个lambda作为模板参数的业务是一条红鲱鱼。我们可以用普通的、旧的int作为参数,也可以得到类似的散度。

template<int>
struct A{};

template<class = A<0>>
struct B : B<> {};

template<int z>
struct B<A<z>> {};

B<int> x;

int main() {}

Clang仍然抱怨,但现在GCC也抱怨。

 类似资料:
  • 本文向大家介绍C语言的递归思想实例分析,包括了C语言的递归思想实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例分析C语言的递归思想,分享给大家供大家参考之用。具体方法如下: 通俗点来说,递归就是自己调用自己。 递归的难点一是理解递归的执行调用过程,二是设置一个合理的递归结束条件。 下面来看一段摘自书中的简单程序: 该程序用来计算阶乘,分别采用循环和递归实现。用语言来描述一下递归的执行过程

  • 主要内容:递归的进入,递归的退出,递归的条件,更多关于递归函数的内容一个函数在它的函数体内调用它自身称为 递归调用,这种函数称为 递归函数。执行递归函数将反复调用其自身,每调用一次就进入新的一层,当最内层的函数执行完毕后,再一层一层地由里到外退出。 递归函数不是C语言的专利, Java、 C#、 JavaScript、 PHP 等其他编程语言也都支持递归函数。 下面我们通过一个求阶乘的例子,看看递归函数到底是如何运作的。阶乘 n! 的计算公式如下: 根据公式编写如

  • 根据我的尝试和错误,答案似乎是否定的,这是一个简单的 将为班上的所有成员工作。然而,我读过的代码建议不是这样,如果能给出具体的答案,我将不胜感激。

  • 我是新的编码和需要作出曼德尔布罗特函数。对于那些不知道的人来说,Mandelbrot集合是一组复数。从本质上讲,你可以从一个复数开始,然后把它平方,然后把它加到原来的复数中。例如,如果我使用数字1,集合将是0、1、2、5、26。。。我从0,1,(1^2)1=2,(2^2)1=5,(5^2)1=26得到这个值。现在,我的递归函数应该使用两个输入来求这个集合的和:一个数字n,它是我们进入集合的距离。例

  • 本文向大家介绍C#中的递归APS和CPS模式详解,包括了C#中的递归APS和CPS模式详解的使用技巧和注意事项,需要的朋友参考一下 累加器传递模式(Accumulator passing style) 尾递归优化在于使堆栈可以不用保存上一次的返回地址/状态值,从而把递归函数当成一个普通的函数调用。 递归实际上是依赖上次的值,去求下次的值。 如果我们能把上次的值保存起来,在下次调用时传入,而不直接引

  • 本文向大家介绍C语言数组栈实现模板,包括了C语言数组栈实现模板的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了C语言数组栈实现模板的具体代码,供大家参考,具体内容如下 SeqStack.h SeqStack.cpp 函数实现 数组栈测试程序 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。