C++ 如何在分离声明和定义时为友元函数指定默认参数

C++ 如何在分离声明和定义时为友元函数指定默认参数,c++,C++,我有一个函数模板,我声明它是我的类的朋友。问题是,我想将声明和定义分开,因为我不想把X的主体弄得乱七八糟,但在使用t()的默认参数时遇到了问题: struct X { 模板 f(T); }; 模板 void f(T=T()){} //错误:无法将默认参数添加到具有 //已经宣布 //void f(T=T()){} // ^ ~~~ //main.cpp:9:17:注意:前面的模板声明在这里 //f(T); // ^ 如果我将其切换为在声明中

我有一个函数模板,我声明它是我的类的朋友。问题是,我想将声明和定义分开,因为我不想把
X
的主体弄得乱七八糟,但在使用
t()的默认参数时遇到了问题:

struct X
{
模板
f(T);
};
模板
void f(T=T()){}
//错误:无法将默认参数添加到具有
//已经宣布
//void f(T=T()){}
//          ^   ~~~
//main.cpp:9:17:注意:前面的模板声明在这里
//f(T);
//                 ^
如果我将其切换为在声明中使用默认参数,那么编译器将输出一条消息,告诉我必须在那里定义函数,但我不想这样做


如何为友元函数模板提供默认参数,同时将定义和声明分开?

对于函数模板,您只能在任何给定范围的第一个声明中写入默认参数;事实上,还有另一条规则禁止在友元声明中写入默认参数:

[C++11:8.3.6/4]:
对于非模板函数,可以在同一范围内函数的后续声明中添加默认参数。[…]如果友元声明指定了默认参数表达式,则该声明应为定义,且应为翻译单元中函数或函数模板的唯一声明

然而,没有什么能阻止您在添加其他声明之前添加另一个声明,这次不是一个朋友声明,并将默认参数放在上面

因此,为了:

  • 函数模板声明,带有默认参数
  • 带有友元声明的类定义
  • 函数模板的定义

  • 我认为如果你在交友之前声明模板函数,它会起作用,但是我不知道你的main.cpp需要测试什么。您是否尝试过这个(编辑:这似乎对coliru有效,但我无法测试您的真实场景)

    模板
    空f(T=T());
    结构X
    {
    模板
    f(T);
    };
    模板
    空f(T){}
    
    你能提供一个完整的例子来重现你的问题吗?我想我们需要
    main.cpp
    来测试你的代码。@MarkB我刚刚发现它只在中给出了一个错误,但在中没有。
    struct X
    {
        template <class T>
        friend void f(T t);
    };
    
    template <class T>
    void f(T t = T()) {}
    
    // error: default arguments cannot be added to a function template that has
    // already been declared
    // void f(T t = T()) {}
    //          ^   ~~~
    // main.cpp:9:17: note: previous template declaration is here
    //     friend void f(T t);
    //                 ^
    
    template <class T>
    void f(T t = T());
    
    struct X
    {
        template <class T>
        friend void f(T t);
    };
    
    template <class T>
    void f(T t) {}