I need to ensure a class is always produced as a shared_ptr. I thus use the idiomatic factory pattern for this:
#include <memory>
class Base {
public:
template <typename Device, typename... Args>
static std::shared_ptr<Device> create_shared(Args&&... args)
{
return std::shared_ptr<Device>(new Device(std::forward<Args>(args)...));
}
protected:
Base() = default;
};
class Derived : public Base {
private:
template <typename Device, typename... Args>
friend std::shared_ptr<Device> Base::create_shared(Args&&... args);
Derived()
: Base()
{
}
};
int main(int, char**) { auto d{Base::create_shared<Derived>()}; }
Link https://godbolt.org/z/f7oz15ren
The above compiles on GCC, but not on MSVC. Changing a few things resolves the issue (on MSVC).
- Move the
create_sharedout of the class to become a free function: https://godbolt.org/z/M65n34ena - Remove the variadic args from the template: https://godbolt.org/z/bEcnPfbhv
I can of course just make it a free function and get on with it, but I'm curious if this is actually an ill-formed C++ program or the compiler is making a mistake here.
Any guru fluent in standardise that can help me out here?