从实际的角度来看,我理解typedef
和test
都有点“多余”,如果我们想要编译以下代码,则需要将其删除:
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
说明符暗示声明的任何变量都是真正的类型。也就是说,typedef
将test
从仅仅变量升级为等同于声明的tagTest
的类型。这就是下面的代码编译的原因(虽然有警告)。
typedef struct tagTest
{
int a;
};
tagTest t;
其中一个答案负责处理多余的test
。但是,可以在没有声明符的情况下使用typedef because“声明命名的类/结构/联合或命名枚举时,Init-declarator-list是可选的”
答案 0 :(得分:4)
Template typedefs,并且引入了C ++ 11 template aliases来解决这些问题。 (CFR)。 C++ template typedefs和wikipedia。
正如您所指出的那样,标准不允许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
声明,在这些情况下未列出:
而且要明确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)