Home > front end >  Is this a bug in C Builder or in MinGw, and MSVC?
Is this a bug in C Builder or in MinGw, and MSVC?

Time:01-06

This 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 in the code is to use a factory function to instantiate derived classes that require a 'post constructor' to be called in 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 that: "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?

Andy

CodePudding user response:

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.

  • Related