8

I found very strange behavior of std::unique_ptr in Visual Studio 2013 and 2017. Let's consider an example:

class Base 
{
public:
    virtual ~Base() = default;
    virtual void Foo() = 0;
};

class Derived : private Base 
{
public:
    void Foo() override
    {
        std::cout << "Foo";
    }
};

void Foo(std::unique_ptr<Base> a)
{
    a->Foo();
}

Foo(std::unique_ptr<Base>(new Derived())); // Compiles

Note that inheritance is private. This example compiles only on Visual Studio. Moreover, the virtual function call works because it is public inheritance. So we have encapsulation violation since the cast from Derived to Base should be inaccessible. Can anybody explain why Visual Studio allows this? Is it a known issue?

The line below doesn't compile for reasonable causes. The only difference between the first and second usages is in the second, the named object B is created.

std::unique_ptr<Base> B(new Derived()); // Doesn't compile

Is it related somehow with this issue which still isn't fixed?

TriskalJM
  • 2,393
  • 1
  • 19
  • 20
Viktor
  • 1,004
  • 1
  • 10
  • 16
  • I'm assuming this is C++? If so, please tag it as such. – BJ Myers Apr 20 '17 at 20:34
  • Interesting. I get the same results as you http://rextester.com/FAMW65845. Doesn't work with clang or g++ – smac89 Apr 20 '17 at 20:47
  • The strange thing is that IntelliSense actually highlights this as an error and shows a proper diagnostic "conversion to inaccessible Base class..." – user7860670 Apr 20 '17 at 21:02
  • 4
    There is nothing strange here. The Visual Studio compiler has never succeeded in remotely getting C++ right. – rubenvb Apr 20 '17 at 21:50
  • This should not compile - `Foo(std::unique_ptr(new Derived())); // Compiles` cannot appear outside of a function. I would recommend updating the code to contain a MCVE – M.M Jun 13 '17 at 00:24

1 Answers1

1

This is fixed in cl version 19.15.26726 (VS 2017 v15.9.0-pre.1.0):

Foo(std::unique_ptr<Base>(new Derived()));

gives

error C2243: 'type cast': conversion from 'Derived *' to 'Base *' exists, but is inaccessible
Swordfish
  • 12,971
  • 3
  • 21
  • 43