Разница тонкая. В первом случае вы создаете класс с именем Foo1
, а во втором случае вы создаете анонимный класс и используете typedef
для предоставления псевдонима Foo2
.
Третий вариант будет:
typedef class Foo3 {
public:
void bar() {}
} Foo3;
Это создаст класс с именем Foo3
, а создаст псевдоним Foo3
для ссылки на него.
Тонкости заключаются в том, как идентификаторы обрабатываются в языке. Когда в коде присутствует идентификатор, компилятор выполнит поиск, чтобы знал , что это значит. Поиск будет проверяться в каждой области видимости, сначала в глобальном идентификаторе , где определено большинство символов (исключая определенные пользователем типы), и если ему не удается найти идентификатор, он затем просматривает пользователя определяемое пространство идентификаторов . Определяемые пользователем типы принадлежат второму пространству идентификаторов, в то время как typedef
-значные имена присутствуют в первой группе. Только если оба поиска завершатся неудачно, компилятор перейдет к следующей закрывающей области видимости.
Чтобы предоставить простой тестовый пример, в котором различия заметны:
class A {};
typedef class {} B;
typedef class C {} C;
void A(); // correct: no collision
//void B(); // error, identifier B already used with a different meaning!
//void C(); // "
namespace test {
void B();
void C();
void f() {
class A a; // creates variable of type ::A
A(); // calls function ::A
B(); // calls function test::B()
//class B b; // error: B does not denote a user-defined type name
C(); // calls function test::C()
class C c; // creates variable of type ::C
}
}