You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

静态可变参数模板友元函数是否符合C++标准?

问题

我需要确保类始终以shared_ptr的形式被实例化,因此采用工厂模式编写了代码。这段代码能在GCC中编译通过,但在MSVC中编译失败。我发现两种修改方式可以解决MSVC的编译问题:

  • 将create_shared移出类作为自由函数
  • 移除模板的可变参数

想明确:这段代码是否属于不合规的C++程序,还是MSVC编译器存在问题?

示例代码
#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>()}; }
分析与结论

这段代码完全符合C++标准,编译失败是MSVC编译器的实现缺陷导致的。

具体原因:

  • 当Derived将Base的可变参数模板成员函数create_shared声明为友元时,MSVC在解析该友元声明的模板参数绑定关系时存在逻辑错误,无法正确识别create_shared的实例化有权访问Derived的私有构造函数。
  • GCC对这种友元模板的解析严格遵循标准,能够正确处理权限校验,因此可以正常编译。

你提到的两种解决方法都是绕开MSVC缺陷的可行方案:

  1. 将create_shared改为自由函数后,友元声明的结构更简单,MSVC能正确处理权限检查。
  2. 移除可变参数后,模板参数列表简化,避免触发MSVC的解析错误逻辑。

内容的提问来源于stack exchange,提问作者SupAl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:30:01