Is a static variadic template friend function legal?

78 views Asked by At

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).

  1. Move the create_shared out of the class to become a free function: https://godbolt.org/z/M65n34ena
  2. 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?

0

There are 0 answers