c++ - 在模板类中声明与朋友相同的模板类?
问题描述
考虑以下:
template<std::integral T>
class Integer {
T value;
template<std::integral T2>
friend class Integer;
public:
template<std::integral T2>
friend bool operator==(Integer<T> x, Integer<T2> y) {
return x.value == y.value;
}
};
该类Integer
定义友operator==
元来比较具有不同模板参数的其他实体,并将模板Integer
类声明为友元类。
但是当我比较两个具有不同模板参数的对象时:
Integer<int> x;
Integer<long> y;
x == y;
<source>:11:25: error: 'long int Integer<long int>::value' is private within this context
11 | return x.value == y.value;
| ~~^~~~~
这让我有点吃惊。在我看来,它应该是格式良好的,因为operator==
是 的朋友Integer<int>
,并且Integer<long>
是 的朋友Integer<int>
,所以operator==
也应该有访问 的成员的权限Integer<long>
。
那么我应该信任哪个编译器?
更新
这是CWG1699。
解决方案
[班级.朋友]
10友谊既不是遗传的,也不是传递的。[示例 8:
class A { friend class B; int a; }; class B { friend class C; }; class C { void f(A* p) { p->a++; // error: C is not a friend of A despite being a friend of a friend } }; class D : public B { void f(A* p) { p->a++; // error: D is not a friend of A despite being derived from a friend } };
——结束示例]
实例化Integer<int>
“注入”以下函数:
template<std::integral T2>
friend bool operator==(Integer<int> x, Integer<T2> y)
现在,虽然Integer<int>
可能是 的朋友Integer<long>
,但operator==
添加的不是。最多只是一个朋友Integer<int>
。所以它不能访问Integer<long>
. 当然,同样的分析也适用于另一个方向(这并不重要,因为重写的候选人被认为是较差的匹配1)。
如果你想要混合比较,你需要对称。两个参数都必须是未知Integer
的特化(带有自己的模板参数),并且类模板需要与操作符友好。
不幸的是,这也意味着不能内联定义运算符(因为每个实例化都会“注入”并重新定义它)。所以这是可行的解决方案:
template<std::integral T>
class Integer {
T value{};
public:
template<std::integral T2, std::integral T3>
friend bool operator==(Integer<T2> x, Integer<T3> y);
};
template<std::integral T2, std::integral T3>
bool operator==(Integer<T2> x, Integer<T3> y) {
return x.value == y.value;
}
1 over.match.best.general/2.8 - “......如果...... F2是一个重写的候选者([over.match.oper])和F1 不是”
推荐阅读
- google-chrome-extension - 与 Progressive Web Apps (PWA) 交互的 Chrome 扩展
- kotlin - Kotlin 无法通过反射访问委托方法:“java.lang.NoSuchMethodException”
- kerberos - 应如何部署 kerberos 委派
- c# - C++/CLI:在 C#.NET 应用程序中返回对非托管对象的引用
- java - 获取多个条目中一行的最大值
- r - 如何在 R 中使用 Leaflet.MarkerCluster.PlacementStrategies 子插件
- javascript - 循环遍历json中的多个项目并分配变量
- javascript - 没有在正则表达式中捕获最后一组
- php - Html 表单不调用操作
- python - django模板中的变量变量