如何正确重载运算符<<对于具有嵌套私有类集合的类?

How to properly overload the operator<< for a class with a collection of nested private classes?

本文关键字:lt 集合 嵌套 何正确 重载 运算符 于具      更新时间:2023-10-16

我想为我的模板类实现operator<<,以便它可以将它包含的所有元素打印到给定的std::ostream&。问题是,我似乎无法让它识别我定义的函数。

我得到的错误是
error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Outer<int>::Inner')
         os << inner << ", ";
         ~~~^~~~~~~~

理想情况下,我不想让函数内联定义,但我甚至不能让它内联工作。在下面的代码中,您可以看到我已经注释掉了在类声明之外定义它的尝试。它会产生与上面相同的错误。

这个问题建议将操作符作为类的友元。我已经试过了所有我能想到的方法,但还是不管用。

代码:

#include <iostream>
template<class T>
class Outer {
    class Inner {
        T item;
        template<class T_>
        friend std::ostream& operator<<(std::ostream& os, const typename Outer<T_>::Inner& inner) {
            os << inner.item;
            return os;
        }
        template<class T_>
        friend std::ostream& operator<<(std::ostream& os, const Outer<T_> outer);
    };
    std::vector<Inner> inner_items;
    template<class T_>
    friend std::ostream& operator<<(std::ostream& os, const Outer<T_> outer);
    template<class T_>
    friend std::ostream& operator<<(std::ostream& os, const typename Outer<T_>::Inner& bar);
};
/*template<class T>
std::ostream& operator<<(std::ostream& os, const typename Outer<T>::Inner& bar) {
    os << inner.item;
    return os;
}*/
template<class T>
std::ostream& operator<<(std::ostream& os, const Outer<T> outer) {
    for (typename Outer<T>::Inner inner : outer.inner_items) {
        os << inner << ", ";
    }
    return os;
}

int main()
{
    Outer<int> outer;
    std::cout << outer;
}

是否为嵌套类型模板的输出操作符:

#include <iostream>
#include <vector>
template<class T>
class Outer {
    class Inner {
        T item;
        friend std::ostream& operator<<(std::ostream& os, typename Outer<T>::Inner const& inner) {
            os << inner.item;
            return os;
        }
        friend std::ostream& operator<<(std::ostream& os, const Outer<T> outer);
    };
    template <typename T_>
    friend std::ostream& operator<< (std::ostream&, Outer<T_> const&);
    std::vector<Inner> inner_items;
};
template<class T>
std::ostream& operator<<(std::ostream& os, Outer<T> const& outer) {
    for (typename Outer<T>::Inner const& inner : outer.inner_items) {
        os << inner << ", ";
    }
    return os;
}
int main()
{
    Outer<int> outer;
    std::cout << outer;
}

有少量的const&和必要的friend声明。

您不需要(也不想)在Inner中进行模板化,只需使用类型:

class Outer {
    class Inner {
        T item;
        friend std::ostream& operator<<(std::ostream& os, const Inner& inner) {
            os << inner.item;
            return os;
        }
        // ...

你上面写的失败了,因为你在Outer<T>::Inner中定义了一个自由函数,即operator<<(..)。第二个形参是Outer<T_>::Inner,编译器不能从Inner转换到定义它的类型。