Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using "using" in public to inherit private constructor does not make it public

"using" a private member variable makes it a public member but the constructor stays private. Example:

class MyClass;

class Base
{
  private:
    Base(float v) : m_v{v} {}
    float m_v;

    friend MyClass;
};

class MyClass: public Base
{
  public:
    using Super = Base;

    using Super::Super; // this is still private
    using Super::m_v; // this is public
};

int main()
{
  MyClass x{3.4f}; // error - calling a private constructor of class 'Base'
  (void)x.m_v; // not an error

  return 0;
}

Is there any other way other than writing an universal ctor like this?

template<typename... Args>
MyClass(Args&&... args) : Super(std::forward<Args>(args)...) {}
like image 340
hasan Avatar asked Nov 08 '22 23:11

hasan


1 Answers

http://en.cppreference.com/w/cpp/language/using_declaration#Inheriting_constructors contains the following passage :

It has the same access as the corresponding base constructor. It is constexpr if the user-defined constructor would have satisfied constexpr constructor requirements. It is deleted if the corresponding base constructor is deleted or if a defaulted default constructor would be deleted (except that the construction of the base whose constructor is being inherited doesn't count). An inheriting constructor cannot be explicitly instantiated or explicitly specialized.

It refers to the inherited constructor. I'm not sure why, but it would appear that your approach is explicitly forbidden. The usual solution is to define a universal forwarding constructor.

like image 101
François Andrieux Avatar answered Nov 14 '22 22:11

François Andrieux