具有定义模板还是非模板的友元函数
Friend function with a definition - template or non-template?
假设我们有以下代码:
template<class T> struct S;
template<class T> void operator++(S<T>);
template<class T> struct S {
friend void operator++(S);
};
template<class T>
void operator++(S<T>) {}
int main() {
S<int> s;
++s;
}
这将编译但不会链接,因为friend
声明引入了从未定义过的非模板operator++
。
这个常见问题解答如下(bold是我的(:
解决方案是在检查类主体时说服编译器,
operator++
函数本身就是一个模板。有几种方法可以做到这一点;
第一种方法是将<>
添加到朋友声明中,我在这里不考虑它。第二个是"定义类主体内的友元函数":
template<class T> struct S {
friend void operator++(S) { }
};
引用表明void operator++(S)
现在是一个函数模板,而不是一个非模板函数。是吗?
它不是模板,因为它的声明不是模板的声明(即使它出现在模板声明本身内部(。
[临时好友](强调矿(
1类或类模板的朋友可以是函数模板或类模板,函数模板或类的专门化模板或非模板函数或类对于好友功能不是模板声明的声明:
如果友元的名称是一个合格或不合格的模板id,则友元声明指的是函数的特殊化模板,否则,
如果朋友的名称是合格的id并且在指定的类或命名空间中找到匹配的非模板函数,友元声明指的是该函数,否则为
如果好友的名称是合格的id,并且在指定的类或命名空间中找到了匹配的函数模板,则该好友声明指的是该函数的推导特殊化template([temp.decture.dell](,否则,
名称应为声明(或重新声明(非模板函数的非限定id。
[示例:
template<class T> class task; template<class T> task<T>* preempt(task<T>*); template<class T> class task { friend void next_time(); friend void process(task<T>*); friend task<T>* preempt<T>(task<T>*); template<class C> friend int func(C); friend class task<int>; template<class P> friend class frd; };
这里,任务类模板的每个专门化都具有以下功能
next_time
作为朋友因为process
没有显式模板参数,任务类模板的每个专门化都有适当类型的函数process
作为朋友,并且该朋友不是函数模板专用化;因为朋友preempt
有一个显式模板参数T
,每个专门化task
类模板的功能模板CCD_ 12作为好友;以及task
类模板具有函数的所有特殊化模板CCD_ 14作为好友。类似地task
类模板具有类模板专业化task<int>
作为朋友,拥有班上所有专业模板CCD_ 17作为好友。—结束示例]
虽然示例是非规范性的,但引用中的示例阐明了先前规范性文本的意图。由于友元运算符声明不是模板声明,因此应用粗体文本。因此,它声明了一个非模板函数。
使用
template<class T> struct S {
friend void operator++(S s) { }
};
operator ++
不再是模板。
对于更规则的函数(operator
的用法与函数略有不同(,它可能允许推导:
template<class T> struct S {
S(T t);
friend void foo(S lhs, S rhs) { }
};
template <typename T>
void bar(S<T> s, T t)
{
foo(s, t); // would not work if foo was template, would require foo<T>(s, t);
foo(s, {t}); // would not work if foo was template, would require foo<T>(s, {t});
}
- C++模板来检查友元函数的存在
- 如何使用单独文件中的派生类访问友元函数对象
- 模板化的类和友元函数
- 友元函数无法访问私有数据成员 (c++)
- 继承和友元函数,从基类访问受保护的成员
- 如何在友元函数中使用静态成员而不添加前缀 [类名]::
- 在模板类之外定义友元函数的正确方法是什么?
- 2个模板化类的非模板友元函数未定义引用错误
- C++ 友元函数和私有构造函数
- 使第二个类的构造函数成为第一个类中的友元函数
- 未定义的类模板不会实例化以检查友元函数
- C++类中的友元函数有问题?
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 模板类中的模板友元函数
- C++ 17 个友元函数声明和内联命名空间
- 友元函数需要一个帮助程序函数
- 在类内定义的友元函数与类外定义的友元函数的查找规则之间的差异
- 运算符重载在 C++ 中使用友元函数
- 类C++友元函数无法访问封装的类
- 函数指针作为友元函数