使用“struct S”或“S”作为类型名的区别

wim*_*aan 2 c++ constructor struct declaration

在 C 语言中,结构化类型的名称S是 ist struct S

在 C++ 中,也可以用作struct S类型名,而不是像S平常那样使用 for

struct S {};

struct S s1; // also ok in C++
S s2; // normal way in C++
Run Code Online (Sandbox Code Playgroud)

因此,假设在 C++ 中使用struct SorS作为类型名是一个品味问题;-)

但下面的例子中有一些地方struct S是不允许的:

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

typedef S1 S2;

template<typename T>
auto foo(T a) {
//    T::_; // T is deduced to `S` in all cases
    return S1{a};
//    return struct S1{a}; // NOK
}

int main() {
//    foo(struct S1{i}); // NOK
    
    S1 s1;
    foo(s1);
    
    struct S1 s2{2};
    foo(s2);
    
    foo(1);

//    struct S2 s20; // NOK
    S2 s21;    
}
Run Code Online (Sandbox Code Playgroud)

谁能向我解释一下这种不对称性是什么意思?看起来struct S在需要将构造函数调用作为表达式的一部分的情况下是不允许的。S但是,如果也可以编写类型,那么struct S它也应该可以用作struct S{}构造函数调用。

MSa*_*ers 5

C++ 中允许写入的原因之一是:与 C 的兼容性。C 允许您同时struct S1 s1;拥有一个名为 的函数,因此是显式消歧的。C++ 也允许这样做,只是为了向后兼容S1struct S1

但是,在向后兼容性不适用的情况下,C++ 则不适用。例如,C 没有构造函数。

这个问题还有一个令人困惑的地方:

typedef S1 S2;
struct S2 s2;
Run Code Online (Sandbox Code Playgroud)

S2不是struct名称而是别名,并且别名不能使用struct.