2

Possible Duplicate:
Difference between ‘struct’ and ‘typedef struct’ in C++?

An answer to this question led me to wonder about the following:

I presume that defining a class as follows:

typedef class {int i;} C;

would be completely equivalent to defining it in the conventional manner:

class C
{
   int i;
};

Is this presumption correct?

Community
  • 1
  • 1
DuncanACoulter
  • 2,095
  • 2
  • 25
  • 38

5 Answers5

4

In this isolated example they are functionally the same, at least from the outside.

However there are differences. One instance in particular, you cannot declare a constructor for a struct or a class declared in this way, simply because the class is unnamed. Similarly you cannot declare any function that involves the class' name. Here are some examples:

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

You also cannot forward declare an anonymous class:

class Gizmo;

In C++ I have never seen a case where typedefing an anonymous struct or a class is preferable to simply declaring a class or a struct that is named. In some cases the traditional method is definitely preferred. The moral of the story is: don't use typedef class {} Name; in C++. It buys you nothing, and costs you something.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • "you cannot declare a constructor" -- or destructor, copy-/move-assignment operator or anything that involves the classes name, obviously. – Xeo Oct 30 '12 at 13:01
  • `typedef struct { ... } name` is mostly seen in code that must retain binary compatibility with pre - C'99 libraries, where the type space and tag space where distinct. (for example, win32 API or X11 API) – Emilio Garavaglia Oct 30 '12 at 13:08
  • One thing you, interestingly, *can* do is define member functions out-of-class, since you're allowed to use a typedef-name for the class-name here. See also [this question](http://stackoverflow.com/q/9146167/500104). – Xeo Oct 30 '12 at 13:11
  • Although there are other good / correct answers I'm accepting this one because I should have seen the whole "anonymous definition means that things needing the name wont work" aspect. – DuncanACoulter Oct 30 '12 at 13:19
  • One thing it does buy you, is that it prevents anyone naming a function `Name` (which could unintentionally interfere with attempts to construct a temporary using `Name()`). See Pubby's answer. But the advice not to use `typedef class {} Name;` is still sound, since if you want that feature you can get it by `typedef class Name {} Name;` – Steve Jessop Oct 30 '12 at 14:11
2

From a practical standpoint yes, because the standard says (9.1/5) that

A typedef-name (7.1.3) that names a class type, or a cv-qualified version thereof, is also > a class-name. If a typedef-name that names a cv-qualified class type is used where a class-name is required, the cv-qualifiers are ignored.

7.1/3 says:

A name declared with the typedef specifier becomes a typedef-name. Within the scope of its declaration, a typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier in the way described in Clause 8. A typedef-name is thus a synonym for another type.

From a theoretical standpoint no, because you could (and indeed I see people already have) draft programs that are valid or invalid depending on which version was used, since 7.1/3 continues from where I cut it off to say:

A typedef-name does not introduce a new type the way a class declaration (9.1) or enum declaration does.

Jon
  • 428,835
  • 81
  • 738
  • 806
2

I believe this is a duplicate question (can't find), but if not, observe that this compiles:

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

class C x;

while this won't:

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

C x;

The name spaces are different.

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • You're right the latter doesn't compile and they do seem to occupy different namespaces, cool. +1 for showing me that you can have a class and a function sharing the same name (its just something I'd subconsciously avoided doing). – DuncanACoulter Oct 30 '12 at 13:14
0

They're not equivalent. In particular,

int main()
{
    class C c;
}

will only compile for one of the two definitions.

avakar
  • 32,009
  • 9
  • 68
  • 103
0

Here is yet another difference: the latter can be forward-declared, the former can't.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510