mardi 3 novembre 2015

C++11 seems impossible to access a protected member through a shared_ptr

It looks like it is not possible to access a protected member through a shared_ptr. Here is a minimal example that doesn't compile:

// compile with g++ -std=c++11 protect.cpp

#include <iostream>
#include <memory>

class C
{
   public:
      C(int xval = 0) : x(xval) {}

   protected:
      int x = 0;
};

class D : public C
{
   public:
      D(int xval = 0) : C(xval) {}
      void print_sum( const std::shared_ptr<C>& other );
};

void D::print_sum( const std::shared_ptr<C>& other )
{
   int sum = x + other->x;
   std::cout << "the sum is " << sum << std::endl;
}

int main( int argc, char** argv, char** envp)
{
   std::shared_ptr<C> first = std::make_shared<C>(2);
   std::shared_ptr<D> second = std::make_shared<D>(3);

   second->print_sum( first );
   return 0;
}

And here are the specific error messages I get:

$ g++ -std=c++11 protect.cpp
protect.cpp: In member function ‘void D::print_sum(const std::shared_ptr<C>&)’:
protect.cpp:13:15: error: ‘int C::x’ is protected
       int x = 0;
               ^
protect.cpp:25:25: error: within this context
    int sum = x + other->x;

It seems strange that D doesn't have access to x even though D is derived from C, and I always thought a derived class could use protected base class members.

This problem isn't really a show-stopper for me; in my use case, C and D are going to be implemented as part of the same patch set, so it's easy enough to just make x public as a workaround. But is there a more "idiomatic" way to make this code work?

Just in case this is a gcc bug, here are the versions I'm using:

$ cat /etc/issue
Ubuntu 14.04.3 LTS \n \l

$ g++ --version
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Aucun commentaire:

Enregistrer un commentaire