简体   繁体   中英

Is this a bug in C++ Builder or in MinGw, and MSVC?

The code below is based on the CPP Core Guidelines , Appendix C, "Discussion: Use a factory function if you need "virtual behavior" during initialization"

The idea of the code is to use a factory function to instantiate derived classes that require a 'post constructor' to be called in the derived class.

The code I have is this:

#include <iostream>
#include <memory>

using namespace std;

class B {
protected:
    class Token {};

public:
    // constructor needs to be public so that make_shared can access it.
    // protected access level is gained by requiring a Token.
    explicit B(Token) { /* ... */ }  // create an imperfectly initialized object

    template<class T>
    static shared_ptr<T> create()    // interface for creating shared objects
    {
        auto p = make_shared<T>(typename T::Token{});
        p->post_initialize();
        return p;
    }

private: //change to protected and it compiles in C++ Builder
    void post_initialize()   // called right after construction
    { /* ... */ f(); /* ... */ } // GOOD: virtual dispatch is safe
    virtual void f() = 0;
};


class D : public B {                 // some derived class
protected:
    class Token {};

public:
    // constructor needs to be public so that make_shared can access it.
    // protected access level is gained by requiring a Token.
    explicit D(Token) : B{ B::Token{} } {}
    D() = delete;

protected:

    //Make B:create() a friend so it can access private and protected members...

    template<class T>
    friend shared_ptr<T> B::create();

private: 

    void f() override {
        std::cout << "I'm a D" << std::endl;
    };
};


int main() {

    shared_ptr<B> p = B::create<D>();    // creating a D object

    return 0;
}

This code compiles and runs using MinGW version w64 9.0 and MSVC 2022. However, C++Builder 11.5 Alexandria, Clang compiler, 32-bit and 64-bit, complains:

error: 'post_initialize' is a private member of 'B'

But, if I change class B 's private: section to protected: , C++Builder compiles the code.

I expected C++Builder to compile this, as B::create() should be able to call a private function of B , should it not?

Or, am I wrong, and MinGW and MSVC are incorrectly able to compile this?

I expected C++ Builder to compile this as B::create() should be able to call a private function of B should it not?

Yes, post_initialize is allowed to be used/called like p->post_initialize() from inside B::create() as both belong to the same class.

This looks like a C++ Builder bug as per your error description.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM