You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中使用struct S与S作为类型名的差异及不对称性解惑

C/C++中结构体类型名struct S与S的使用差异

在C语言中,结构体<S>的完整类型名称是<struct S>;而在C++中,声明变量时既可以沿用C的写法用<struct S>作为类型名,也可以直接使用<S>,例如:

struct S {};

struct S s1; // C++中合法,兼容C写法
S s2; // C++的常规简写写法

通常大家觉得这两种写法只是个人习惯差异,但在部分场景下struct S是不被允许的,比如:

struct S1 {
    S1(int x = 0) : x{x} {}
    int x{};
};

typedef S1 S2;

template<typename T>
auto foo(T a) {
//    return struct S1{a}; // 编译报错,不合法
    return S1{a};
}

int main() {
//    foo(struct S1{1}); // 编译报错,不合法

    struct S1 s2{2};
    foo(s2);

//    struct S2 s20; // 编译报错,不合法
    S2 s21;
}

为什么会存在这种使用不对称?

这种差异本质是C++的语法规则划分导致的:

  • struct S属于类型说明符,仅适用于声明语境(比如变量、对象的声明语句);
  • 而表达式语境(比如创建临时对象、模板参数传递等)要求使用类型-id——也就是可以直接被表达式识别的完整类型名称,S才是符合要求的类型-id,struct S不能作为类型-id使用。

具体场景解释:

  • return struct S1{a};和foo(struct S1{1});不合法:
    在表达式里调用构造函数创建临时对象时,必须用类型-id来指定类型。struct关键字在这里是用于声明结构体的语法标记,属于声明语境的冗余写法,不能出现在表达式的类型引用中,因此struct S1{a}这种写法不符合语法规则。

  • struct S2 s20;不合法:
    S2是typedef定义的类型别名,本身已经是完整的类型名。struct关键字只能搭配原本的结构体类型声明使用,无法和类型别名结合——编译器无法识别struct S2对应的实际类型,因此报错。

简单来说,C++保留struct S声明变量的写法只是为了兼容C代码,但这种写法的适用范围被严格限制在声明语境,不能扩展到表达式语境中。

内容的提问来源于stack exchange,提问作者wimalopaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:24:27