我有一个功能模板,我宣称我是班上的朋友。问题是,我想保持声明和定义分开,因为我不想混淆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>
如何在保持定义和声明分开的同时为朋友函数模板提供默认参数?
答案 0 :(得分:4)
对于函数模板,您只能在任何给定范围内的 first 声明中编写默认参数;事实上,还有另一条规则禁止在朋友声明中编写默认参数:
[C++11: 8.3.6/4]:
对于非模板函数,可以在稍后的同一范围内的函数声明中添加默认参数。 [..] 如果朋友声明指定了默认参数表达式,则该声明应该是一个定义,并且应该是翻译单元中函数或函数模板的唯一声明。
然而,没有什么可以阻止你添加另一个声明,这次不是朋友声明,在其他一切之前,并把你的默认参数放在那里。
所以,按顺序:
答案 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) {}