0

I would like to provide access to an existing type from base class inside child class.

I found two different ways :

struct A {
    typedef int mytype;
};

struct B {
    typedef double mytype;
};

I can "include" the type with a using declaration :

struct C : A, B {
    using typename A::mytype;
};

Or I can create a type alias :

struct C : A, B {
    typedef A::mytype mytype;
    using mytype = A::mytype; //C++11
};
  1. Is there any difference ?
  2. What are the pros and cons of each syntax ?
  3. Which one is the most used/recommended ?

Thank you.

Related question : Using-declaration of an existing namespace type vs creating a type alias

Baptistou
  • 1,749
  • 1
  • 13
  • 24
  • 2
    Are you aware that `class child` inherits also the types of `class base`? I.e. Even without `typedef` or `using`, `child::mytype` will be recognized when `mytype` is declared in `base` and `child` is derived from `base`. [Example](http://coliru.stacked-crooked.com/a/43841cabacf65ea4) – Scheff's Cat Oct 18 '19 at 10:34
  • This is a very simple code example, but in my case I have a more complex hierarchy and multiple inheritance which prevent parent types to be accessed directly in child class. – Baptistou Oct 18 '19 at 10:39
  • For the simple case, it works like shown above. If you need additional restrictions, try to express this in your [mcve]. Even for multiple inheritance, this should be possible with only a few additional lines of code. ;-) Btw. I would try to avoid multiple inheritance if possible, and most times it is. Aggregation often works as well. – Scheff's Cat Oct 18 '19 at 10:41
  • Both the `using` and `typedef` as you are employing them declare a alternative name for a type, rather than creating a new type. In most contexts, they are equivalent - and the choice between them is subjective. `using` works better with templates though - for example, `template using Map = std::map >` can be replicated using a `typedef`, but not particularly easily. – Peter Oct 18 '19 at 10:44

1 Answers1

2

There is a difference. Consider what would happen if your structs A and B were defined as:

struct A {
protected:
    int mytype;
};

struct B {
protected:
    double mytype;
};

In that case

struct C : A, B {
    using typename A::mytype;  // Would compile, but is mytype a type or
                               // an exposed member of the base class?
    //using mytype = A::mytype;  // Would not compile
};

In your case I would recommend using using mytype = A::mytype; as it is less ambiguous.

MannyC
  • 46
  • 4
  • 1
    After some tests, it looks like a gcc bug because clang complains ```error: 'typename' keyword used on a non-type``` – Baptistou Oct 23 '19 at 11:41
  • That is interesting. Seems to me that only clang complains about this, gcc and MSVC do not even generate warnings. https://en.cppreference.com/w/cpp/language/using_declaration indicates that `typename` is optional and "may be used as necessary to resolve dependent names". – MannyC Oct 23 '19 at 12:29