如何在分离声明和定义时给朋友函数一个默认参数

时间:2014-11-03 18:58:37

标签: c++

我有一个功能模板,我宣称我是班上的朋友。问题是,我想保持声明和定义分开,因为我不想混淆X的主体,但是当使用T()的默认参数时我遇到了问题:< / p>

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);
//                 ^

如果我将其切换为在声明中使用默认参数,那么编译器会输出一条消息,说明我必须定义那里的函数,但我不想这样做。< / p>

如何在保持定义和声明分开的同时为朋友函数模板提供默认参数?

2 个答案:

答案 0 :(得分:4)

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

  

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

然而,没有什么可以阻止你添加另一个声明,这次不是朋友声明,在其他一切之前,并把你的默认参数放在那里。

所以,按顺序:

  1. 声明功能模板,默认参数
  2. 与朋友声明的班级定义
  3. 功能模板的定义

答案 1 :(得分:2)

我认为如果你在知道模板功能之前宣布模板功能可行,但我无法弄清楚你的main.cpp必须测试什么。你试过这个吗(编辑:这似乎适用于coliru,但我无法测试你的真实场景)。

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) {}