Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

std::make_shared<>(), has access to protected constructor

tpucke
Beginner
1,091 Views
Hello, I'm using Intel's 12.1 compiler with Visual Studio 2010 IDE, making 64 bit target. See code in 2 attached files. The problem is that this code compiles and it should trigger an error. As expected, it fails with the Microsoft compiler with error C2248 cannot access protected member... . The Worker class constructor is not public and so it should not be accessible from std::make_shared(...). Is this a compiler defect? I have tried things such as making the Worker constructor private with the same outcome. I tried completely removing the Worker constructor with 2 arguments, and the code still compiles with no complaint. I tried making the call to std::make_shared in the constructor body rather than in member initialization. No improvement. It seems like the compiler is not checking for access to construct the object managed by the std::shared_ptr<...>. Thanks for looking
0 Kudos
7 Replies
SergeyKostrov
Valued Contributor II
1,091 Views
Thanks for the test case!
0 Kudos
Georg_Z_Intel
Employee
1,091 Views
Hello, I can reproduce the problem you described. In my opinion this should not be the case -- any compiler has to error here. Hence I've filed a defect ticket (DPD200239413) and let you know about the status. Thank you for the great reproducer! Best regards, Georg Zitzlsberger
0 Kudos
SergeyKostrov
Valued Contributor II
1,091 Views
Hi everybody, >>...The Worker class constructor is not public and so it should not be accessible from std::make_shared(...). Is this a compiler defect? Yes. Even if a member mpWorker is declared without the std::shared_ptr template class ( not as a smart pointer ): ... Worker * operator ->() const; protected: // std::shared_ptr< Worker > mpWorker; Worker *mpWorker; }; ... any C++compiler should fail with some error, like: ...'Worker::Worker' : cannot access protected member declared in class 'Worker'... Best regards, Sergey
0 Kudos
SergeyKostrov
Valued Contributor II
1,091 Views
Here is a test-case that you could consider as a workaround ( passed with 5 different C/C++ compilers ): ... class Worker { public: Worker(); virtual ~Worker(); protected: Worker( string const &vClientName, string const &vUserName ); public: void SetNames( string const &vClientName, string const &vUserName ) { mClientName = vClientName; mUserName = vUserName; }; protected: string mClientName; string mUserName; }; class Handle { public: Handle( string const &vClientName = "unknown", string const &vUserName = "unknown" ); Handle( Handle const &vRhs ); virtual ~Handle(); public: Worker * operator ->() const; protected: // std::shared_ptr< Worker > mpWorker; Worker mpWorker; }; Worker::Worker() { } Worker::Worker( string const &vClientName, string const &vUserName ) { mClientName = vClientName; mUserName = vUserName; } Worker::~Worker() { } /* Handle::Handle( string const &vClientName, string const &vUserName ) : // mpWorker( std::make_shared< Worker >( vClientName, vUserName ) ) // mpWorker( Worker( vClientName, vUserName ) ) { } */ Handle::Handle( string const &vClientName, string const &vUserName ) { // Case 1 - Compiling error // (*this).operator->()->mClientName = vClientName; // Cannot be used directly when the member is declared as protected in class 'Worker' // (*this).operator->()->mUserName = vUserName; // Case 2 - Compiling error // mpWorker.mClientName = vClientName; // Cannot be used directly when the member is declared as protected in class 'Worker' // mpWorker.mUserName = vUserName; // Case 3 - Success mpWorker.SetNames( vClientName, vUserName ); // Public 'SetNames(...)' method used instead to initialize members of class 'Worker' } Handle::~Handle() { } Worker * Handle::operator ->() const { return ( Worker * )&mpWorker; } ... void main( void ) { Handle objAccount( "MyClient", "MyUser" ); }
0 Kudos
tpucke
Beginner
1,091 Views
Thanks for the suggestion. I have implemented a pass-key pattern that works around the access issue from std library, since I don't know the scope of the compiler issue.
0 Kudos
SergeyKostrov
Valued Contributor II
1,091 Views
>>... I don't know the scope of the compiler issue... I personally would use a workaround ( Is that a big problem? No. ) because it will take some time to fix the problem with the compiler. At least you should be able to proceed with what you need to do etc.
0 Kudos
Georg_Z_Intel
Employee
1,091 Views
Hello, this problem will be fixed in Intel(R) Composer XE 2013 Update 2 that's scheduled soon. Best regards, Georg Zitzlsberger
0 Kudos
Reply