如何使用嵌套的私有 classes 集合为 class 正确重载 operator<<?

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

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

我得到的错误是

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

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

This question 建议将操作员设为 class 的好友。我用了所有我能想到的方法,但还是不行。

代码:

#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;
}

您不需要(也不想)在 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 到定义它的类型。

不要不要为嵌套类型模板创建输出运算符:

#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 声明。