为什么typedef模板非法?

时间:2015-06-16 07:42:28

标签: c++ templates language-lawyer

从实际的角度来看,我理解typedeftest都有点“多余”,如果我们想要编译以下代码,则需要将其删除:

template< typename type_t >
typedef struct tagTest
{
    int a;
} test;

但是,我认为typedef声明集是声明集的子集。他们碰巧有那个特定的 decl-specifier

是我的合理化
typedef struct tagTest
{
    int a;
} test;

引入标识符test ,声明结构tagTest。如果该解释是正确的,那么标准中的以下段落应该允许template typedef(尽管没有关键字using给出的含义)。

  

模板声明中的声明应    -   (1.1)   声明或定义函数,类或变量,或    -   (1.2)   定义成员函数,成员类,成员枚举或类的静态数据成员   模板或嵌套在类模板中的类,或    -   (1.3)   定义类或类模板的成员模板,或    -   (1.4)   是一个别名声明。

我在推理中看不到错误,但结论是非法的。

解决上述难题的标准的相关部分是什么?

更新 上述推理的一部分使用typedef struct声明结构的事实。据我所知,typedef说明符暗示声明的任何变量都是真正的类型。也就是说,typedeftest从仅仅变量升级为等同于声明的tagTest的类型。这就是下面的代码编译的原因(虽然有警告)。

typedef struct tagTest
{
    int a;
};
tagTest t;

其中一个答案负责处理多余的test。但是,可以在没有声明符的情况下使用typedef because“声明命名的类/结构/联合或命名枚举时,Init-declarator-list是可选的”

3 个答案:

答案 0 :(得分:4)

在C ++ 11之前不允许使用

Template typedefs,并且引入了C ++ 11 template aliases来解决这些问题。 (CFR)。 C++ template typedefswikipedia

正如您所指出的那样,标准不允许typedef存在,代码无效

  

别名声明:

 using identifier attribute-specifier-seqopt= type-id ;

typedef声明不是别名声明

此外,如果您要声明一个类模板,则不能拥有声明器,标准明确禁止它

[温度] / P3

  

在模板声明,显式特化或显式实例化声明中的init-declarator-list   最多应包含一名申报人。 当这样的声明用于声明类模板时,   不允许声明者

所以即使以下也不会编译

template< typename type_t >
struct tagTest
{
    int a;
} test;

编辑:

没有指明

typedef struct S { };

应该是一个错误,因此gcc和clang都会接受警告。我假设Clang指望 [temp] / 3 发出错误,以防typedef与模板一起使用,而gcc立即拒绝此代码

template<typename T>
typedef struct S { };

(CFR)。 clang bug 22249

答案 1 :(得分:1)

独立于typedef定义的内容,即typedef声明,在这些情况下未列出:

  • [会员]功能
  • [member] class
  • 可变
  • 成员枚举
  • 类模板的静态数据成员/嵌套在类模板中的类
  • 类或类模板的成员模板
  • 别名声明

而且要明确typedef声明不是别名声明别名声明,由标准§7中的语法指定:

  

别名声明

     

using identifier attribute-specifier-seqopt= type-id ;

更不用说如果可行,那么模板using声明就不会像今天那样“酷”,there would be little to no sense to have both

答案 2 :(得分:0)

C不支持模板和

typedef struct tagX {
} X;
C ++中的

语法是残留的C,允许继续支持C头等,而不是在实际的C ++中使用。

上面的C ++语法是

struct X {};

(支架放置时YMMV)