【问题标题】:friend function template with default template argument具有默认模板参数的友元函数模板
【发布时间】:2026-02-08 15:20:05
【问题描述】:

是否允许在朋友声明中为模板参数提供默认值?

class A {
    int value;
public:
    template<class T = int> friend void foo();
};

Visual Studio 2015 似乎允许这样做。 gcc 拒绝它。我在 cppreference 页面上找不到任何内容。

【问题讨论】:

    标签: c++ templates friend forward-declaration default-arguments


    【解决方案1】:

    从 C++11 开始,规则在 14.1[temp.param]/9 中指定

    如果友元函数模板声明指定了默认模板参数,则该声明应为定义,并且应是翻译单元中函数模板的唯一声明。

    当然,直到 C++11,14.1/9 都说“不应在友元模板声明中指定默认模板参数。”

    (上面的内容几乎是逐字复制的,cppreference 在Default template parameters,现在也在Template friends 提到)

    所以,要使您的程序有效 C++,请在类中定义您的朋友模板,而不仅仅是声明。

    【讨论】:

      【解决方案2】:

      如果你真的想让你的函数 foo() 保持全局,你可以试试这个:

      class A
      {
          int value;
      public:
          template<class T> friend void foo();
      };
      
      template<class T = int> void foo()
      {
          //you can use private member of A
          A foo;
          auto value = foo.value;
      }
      

      【讨论】: