Эквивалентность использования typedef и анонимного определения класса для обычного определения класса

Возможный дубликат:
Разница между «struct» и «typedef struct» в C ++?

Ответ на этот вопрос заставил меня задуматься о следующем:

Я предполагаю, что определение класса выглядит следующим образом:

typedef class {int i;} C;

будет полностью эквивалентно определению его обычным способом:

class C
{
int i;
};

Это предположение верно?

2

Решение

В этом изолированном примере они функционально одинаковы, по крайней мере, снаружи.

Однако есть различия. В частности, один экземпляр, вы не можете объявить конструктор для struct или class заявлено таким образом, просто потому, что class безымянный Точно так же вы не можете объявить любую функцию, которая включает имя класса. Вот некоторые примеры:

typedef class
{
public:
Gizmo() : n_(42) {}; // NOT OK
~Gizmo();
Gizmo& operator<<(int n);
private:
int n_;
} Gizmo;

Вы также не можете переслать объявление анонимного класса:

class Gizmo;

В C ++ я никогда не видел случая, когда typedefанонимный struct или class предпочтительнее простого объявления class или struct это называется. В некоторых случаях традиционный метод определенно предпочтительнее. Мораль этой истории такова: не используйте typedef class {} Name; в C ++. Он ничего не покупает и чего-то стоит.

4

Другие решения

Я считаю, что это дублирующий вопрос (не могу найти), но если нет, обратите внимание, что это компилируется:

class C
{
int i;
};
void C() {}

class C x;

пока этого не будет:

typedef class
{
int i;
} C;
void C() {}

C x;

Пространства имен разные.

2

С практической точки зрения да, потому что стандарт говорит (9.1 / 5), что

Typedef-name (7.1.3), в котором указывается тип класса, или его cv-квалифицированная версия, также> class-name. Если используется typedef-имя, которое указывает cv-квалифицированный тип класса, где
имя класса обязательно, квалификаторы cv игнорируются.

7.1 / 3 говорит:

Имя, объявленное с помощью спецификатора typedef, становится typedef-name.
В рамках своего объявления typedef-name синтаксически
эквивалентно ключевому слову и именует тип, связанный с
идентификатор в способе, описанном в разделе 8. Таким образом, typedef-имя является
синоним другого типа.

С теоретической точки зрения нет, потому что вы могли (и я действительно вижу, что у людей уже есть) проекты программ, которые действительны или недействительны, в зависимости от того, какая версия использовалась, поскольку версия 7.1 / 3 продолжается с того места, где я ее обрезал, чтобы сказать:

Typedef-имя делает
не вводите новый тип, как объявление класса (9.1) или объявление enum.

2

Они не эквивалентны. Особенно,

int main()
{
class C c;
}

будет компилироваться только для одного из двух определений.

0

Вот еще одно отличие: последнее может быть объявлено заранее, первое — нет.

0