首页 > 解决方案 > 嵌套派生模板的运算符重载

问题描述

我在派生类和嵌套类的运算符重载方面遇到了一些问题。我尝试了很多方法,但失败了很多次。任何人都可以帮助解决这个问题吗?这是代码:

甲类

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<< 。这里有什么问题?

标签: c++

解决方案


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 找到。


推荐阅读