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

可以在C语言的模板参数列表中定义类型吗?

费学
2023-03-14

在以下模板struct B的定义中,lambda用作非类型模板参数的默认值,并且在lambda的主体中定义了一些类型a

template <auto = []{ struct A{}; }>
struct B {};

Clang和MSVC对此定义没有异议,但GCC抱怨:

错误:“struct”的定义

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

哪个编译器在这里?


共有1个答案

慕皓君
2023-03-14

[temp.param]/2说:

模板参数声明中不应定义类型。

这样看来,GCC拒绝这段代码是正确的:这一禁止并不局限于类型参数的类型id,而是适用于模板参数声明中的任何地方。包括嵌套在lambda中。

另一方面,也可以将其理解为在模板参数中禁止lambda本身。毕竟,lambda表达式隐式定义了类类型([expr.prim.lambda.closure]/1)。

第三方面,我们还有[expr.prim.lambda.closure]/2,其中说明:

闭包类型在包含相应lambda表达式的最小块作用域、类作用域或命名空间作用域中声明。

这里的相关作用域似乎是命名空间作用域。这意味着lambda应该被视为它的类型被声明在模板参数列表之外。但是,lambda体内的声明也应该如此,问题中的定义应该被允许。

就我个人而言,我认为这一标准的缺陷在于这一禁令的范围似乎不明确。

 类似资料:
  • 我发现gcc和clang允许在非类型模板参数类型子句中使用。例如: [live demo gcc][live demo clang] 它是符合标准的功能还是一些gnu扩展?

  • C语言允许宏带有参数。在宏定义中的参数称为“形式参数”,在宏调用中的参数称为“实际参数”,这点和函数有些类似。 对带参数的宏,在展开过程中不仅要进行字符串替换,还要用实参去替换形参。 带参宏定义的一般形式为: #define 宏名(形参列表) 字符串 在字符串中可以含有各个形参。 带参宏调用的一般形式为: 宏名(实参列表); 例如: 在宏展开时,用实参 5 去代替形参 y,经预处理程序展开后的语句

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

  • 每个函数如果独立的存在是没有意义的。所以函数之间必然是相互通信的。而最常见也最常用的函数通信的方式就是函数的参数与返回值。而函数的参数是更为重要一些。因为纯粹没有参数传入的函数是很好的。因为要实现某种功能,处理某些数据,就要从外界获得数据。 1. 值传入 值传入是在函数调用过程中,将原函数的数值复制一份后,将副本再传入调用的函数中。在函数中操作的都是副本的数值。对原有函数中的原变量是没有影响的。

  • 我正在尝试创建一个。我想直接使用它。e、 g.。但是,当从转换为