3

Are there any pitfalls of putting a typedef inside a class if the typedef uses the class it is in as a parameter?

#include <memory>


class Foo{
  public:
    typedef std::shared_ptr<Foo> shared_ptr;
}


void main(){
  Foo x;
  Foo::shared_ptr p = std::make_shared<Foo>();
}

The above code works for me (clang) but I was wondering if the standard had anything to say about it.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
segfault
  • 339
  • 2
  • 8
  • 3
    Yes, this is legal. C++ compilation is not done in a single pass. There's nothing wrong with using a type that has not yet been fully defined in a declaration. You see the same thing in the [CRTP](https://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp). But since you're looking for specifically what the standard has to say about this, I've added the [[tag:language-lawyer]] tag. – Cody Gray - on strike Feb 14 '19 at 03:56
  • What advantage do you see here ? – Sid S Feb 14 '19 at 04:27
  • @SidS It puts the `shared_ptr` typedef inside `Foo`'s scope and can be accessed through `Foo::shared_ptr`. If the typedef was outside of `Foo`, I would have to be careful about remembering what class `shared_ptr` was a pointer for or do `Foo_shared_ptr`, which is ugly. – segfault Feb 14 '19 at 04:36
  • How is `Foo::shared_ptr` better than `shared_ptr` ? The former could mean anything, while the latter has only one meaning. – Sid S Feb 14 '19 at 04:54
  • @SidS I think that issue has to do with why I should typedef in the first place. Given that I do want to typedef, it makes sense to limit its scope to `Foo`. [This post](https://stackoverflow.com/q/759512/5101335) discusses better than I could the pros and cons of internal typedefs. – segfault Feb 14 '19 at 05:06

1 Answers1

4

The typedef inside the Foo class is a declaration and not a definition so it is allowed to do what you are doing. If it were a definition it would not be allowed because the definition of the Foo class is not complete until the closing brace.

6.1 Declarations and definitions [basic.def]

2 A declaration is a definition unless
...

(2.9) — it is a typedef declaration (10.1.3),

But if you did something like this:

class Foo{
  public:
    Foo f; //A definition
}

Foo f will be considered a definition and the compiler will issue an error like:

error: field has incomplete type 'Foo'
    Foo f;
        ^
<source>:1:7: note: definition of 'Foo' is not complete until the closing '}'
class Foo{
Community
  • 1
  • 1
P.W
  • 26,289
  • 6
  • 39
  • 76