运算符<<用于模板类的内部类

时间:2014-09-19 09:07:51

标签: c++ templates c++11

我想实现operator <<来打印模板类的内部类的内容,即X<T>::Y。可以添加所需的任何friend声明。怎么做?

以下是我想在C ++ 11中编译的完整示例:

#include <iostream>

template <typename T>
class X {
public:
    X(T d): y(d) {}

private:
    class Y {
    public:
        Y(T d): data(d) {}

    private:
        T data;

        template <typename U>
        friend std::ostream &operator <<(std::ostream &os, const typename X<U>::Y &y);
    };

    Y y;

    template <typename U>
    friend std::ostream &operator <<(std::ostream &os, const X<U> &x);
};

// This operator is not detected by the operator below
template <typename U>
std::ostream &operator <<(std::ostream &os, const typename X<U>::Y &y) {
    os << "Y(" << y.data << ")";
    return os;
}

template <typename U>
std::ostream &operator <<(std::ostream &os, const X<U> &x) {
    os << "X " << x.y;
    return os;
}

int main() {
    std::cout << X<int>(1);
    return 0;
}

我得到的编译错误是:

error: no match for 'operator<<' (operand types are 'std::basic_ostream<char>' and 'const X<int>::Y')
 os << "X " << x.y;
            ^

1 个答案:

答案 0 :(得分:4)

这不起作用,因为typename X<U>::Y是依赖类型。如果你想打印,例如一个int,编译器是否应该测试U的所有可能类型(由于递归而存在无数多个)以便检查typename X<U>::Y是否为int(考虑模板专业化!)?因此,唯一的可能性是在友元声明中实现该功能:

class Y {
public:
    Y(T d): data(d) {}

private:
    T data;

    friend std::ostream &operator <<(std::ostream &os, Y const& y)
    {
        os << "Y(" << y.data << ")";
        return os;
    }
};

http://ideone.com/dx8Qri