关于 c :Class locals as predicates pre C 11

Class locals as predicates pre C++11

以下代码在使用 GCC 和 Clang 在 C 11 模式下编译时不会出现错误/警告。但是,如果我尝试在没有 C 11 模式的情况下进行编译,并且在第二个范围内发生错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include
#include <vector>

struct astruct
{
   int v;
};

struct astruct_cmp0
{
   bool operator()(const astruct& a0, const astruct& a1) {
     return a0.v < a1.v;
   }
};

int main()
{
   std::vector alist;
   {
      // Works - no errors
      std::stable_sort(alist.begin(),alist.end(),astruct_cmp0());
   }

   {
      struct astruct_cmp1
      {
         bool operator()(const astruct& a0, const astruct& a1) {
           return a0.v < a1.v;
         }
      };

      // error: template argument uses local type 'astruct_cmp1'
      std::stable_sort(alist.begin(),alist.end(),astruct_cmp1());
   }

   return 0;
}

我的问题是:允许本地结构定义的 C 11 更改是什么?有人可以指出标准中的特定部分(也许是第 9.8 节?)


在 C 03 中,函数局部类型不是可行的模板参数。在 C 11 中,函数局部类型是可行的模板参数。 C 03 中的关键引用是 14.3.1 [temp.arg.type] 第 2 段:

The following types shall not be used as a template-argument for a template type-parameter:

  • a type whose name has no linkage
  • ...

在 C 11 中,这个约束被移除了。

关于何时定义链接的相关部分是 3.5 [basic.link](在两个标准中),它相当长并且指向没有通过排除链接的实体,C 03 中的第 8 段:

Names not covered by these rules have no linkage. ...

函数中定义的类型没有在"这些规则"中列出。