10

GCC 4.8.1 accepts

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass<T>::Baseclass;
};

but MSVC does not. On the other hand, MSVC accepts

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass::Baseclass;
};

but GCC does not. Then I've seen another kind of declaration in this questions: c++11 inheriting template constructors

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass::Baseclass<T>;
};

for which MSVC warns about an "obsolete declaration style" and GCC says

prog.cpp:8:24: error: ‘template<class T> class Baseclass’ used without template parameters
        using typename Baseclass::Baseclass<T>;

I thought the first example would be the standard conform syntax. Intuitively, it looks right to me.

What is the c++11 standard conform syntax?

Community
  • 1
  • 1
Niklas R
  • 16,299
  • 28
  • 108
  • 203
  • 3
    What MSVC version? VS2013 does not support inheriting constructors. AFAIK, the first one is the correct syntax. `using Baseclass::BaseClass` should work for cases where `BaseClass` itself is not a class template, but has a constructor template. – Praetorian Sep 19 '14 at 18:47
  • @Praetorian Now that is surprising. But I only ever used the default and copy constructor, and now after testing a different constructor, I see you are right. Are copy and default constructors inherited automatically? – Niklas R Sep 19 '14 at 19:00
  • 1
    You'll have to check the standard, but I'm pretty sure the special member functions are *never* inherited. They may be automatically declared by the compiler in the derived class following the usual rules for their generation. – Praetorian Sep 19 '14 at 19:05
  • According to the [Wikipedia Article](https://en.wikipedia.org/wiki/C%2B%2B11#Object_construction_improvement), all constructors should be inherited. So even something like `Base::Base(int value)`. Edit: And GCC does it: http://ideone.com/J0ToW2 – Niklas R Sep 19 '14 at 19:09
  • 3
    Huh? Why is there a `Baseclass` and a `BaseClass`? – dyp Sep 19 '14 at 19:16
  • 1
    Yes, of course `Base::Base(int)` will be inherited, but that's neither a default nor a copy constructor. See [class.inhctor]/3 which states that default and copy/move constructors are left out from the candidate set of inherited constructors. – Praetorian Sep 19 '14 at 19:17
  • Since members of dependent base classes are not searched for in non-depended contexts, I think you have to provide the template argument for the `BaseClass` before the `::`. – dyp Sep 19 '14 at 19:18
  • 3
    I am pretty sure the correct way to inherit constructors here is `using Baseclass::Baseclass;`, no `typename`, and providing the template argument (at least) left of `::`. – dyp Sep 19 '14 at 19:20

1 Answers1

3

The answer is a bit buried in the standard. A using declaration is defined as (7.3.3):

using [typename] nested-name-specifier unqualified-id;

The nested-name-specifier resolves after some steps into simple-template-id which is defined as

template-name < [template-argument-list] >

In short, the standard conforming syntax is

template <typename T>
class Subclass : public Baseclass<T>
{
public:
    using typename Baseclass<T>::Baseclass;
};
user1978011
  • 3,419
  • 25
  • 38
  • It makes no sense to use `typename` here: you’re not after the injected-class-name of the base, but its constructors. – Davis Herring Sep 13 '21 at 15:17