c++ - 嵌套派生模板的运算符重载
问题描述
我在派生类和嵌套类的运算符重载方面遇到了一些问题。我尝试了很多方法,但失败了很多次。任何人都可以帮助解决这个问题吗?这是代码:
甲类:
template <typename T>
class A {
public:
virtual ~A() = default;
};
template <typename T>
ostream& operator<<(ostream& out, const A<T>& a) {
out << "in A\n";
return out;
}
B类:
template <typename T>
class B : public A<T> {};
template <typename T>
ostream& operator<<(ostream& out, const B<T>& b) {
out << "in B\n";
return out;
}
和测试代码:
A<int> *pa = new B<int>();
B<int> *pb = dynamic_cast<B<int> *>(pa);
cout << *pa << typeid(*pa).name() << endl;
cout << *pb << typeid(*pb).name() << endl;
我从结果中得到了我需要的东西:
在一个
1BIIE
在乙
1BIIE
然后我创建了一个嵌套类,它也是从类 A派生的:
BB::B 类:
template <typename T>
class BB {
public:
class B : public A<T> {};
};
template <typename T>
ostream& operator<<(ostream& out, const typename BB<T>::B& b) {
out << "in BB::B\n";
return out;
}
但是当我用代码测试这个类时:
A<int> *pa2 = new BB<int>::B();
BB<int>::B *pb2 = dynamic_cast<BB<int>::B *>(pa2);
cout << *pa2 << typeid(*pa2).name() << endl;
cout << *pb2 << typeid(*pb2).name() << endl;
我得到了一个意想不到的结果:
在一个
N2BBIiE1BE
在一个
N2BBIiE1BE
似乎编译器没有专门为BB::B重载 operator<< 。这里有什么问题?
解决方案
template <typename T>
ostream& operator<<(ostream& out, const typename BB<T>::B& b);
的类型b
在非推断上下文中。它永远不会T
从这个签名中推断出来。
T
您可以明确地将其称为购买传递。BB<T>::B
或者你可以写一个从to的类型映射B
并得到真正的幻想。但这并不值得。
简单的选择是 Koenig 算子。
template <typename T>
class BB {
public:
class B : public A<T> {
friend ostream& operator<<(ostream& out, const B& b){
out << "in BB::B\n";
return out;
}
};
};
这个 Koenig 运算符是为 的每个实例化生成的非模板函数BB<T>::B
,并且只能通过 ADL 找到。
推荐阅读
- python - 无法使用 OpenCV 4.2 (videoCapture) 打开 .mp4 视频
- mysql - 在不使用 GROUP BY 的情况下标记重复值 MySQL
- apache-spark - 有没有办法在使用 spark 进行插入覆盖时保持适当数量的文件?
- reactjs - 反应JS。在循环中声明的函数包含对变量的不安全引用
- c# - 测试的 TDD 方法问题
- r - 当数据集中已经计算了 SEM 时,将 SEM 条添加到 ggline 图中
- c - 通过设置取消引用的指针将对象从堆栈复制到堆是一种好习惯吗?
- selenium-webdriver - 失败:chrome org.openqa.selenium.WebDriverException:**Selenoid** 发生未知错误
- angular - Ngrx Data GetAll 并修改路径
- c++ - 在第 0 行第 0 列出现错误:转换错误