运营商LT;< C ++中模板类中的成员类型的重载

时间:2016-06-08 13:14:57

标签: c++ templates operator-overloading type-members

在下面的代码中,我有一个模板类,其中包含成员类型(struct Element)。我想重载运算符<<对于成员类型。但是,代码不会编译。

如果有人能指出我哪里出错了,我会很感激吗?

include <iostream>
using namespace std;

// fwd decl
template<class T> class CC;

// operator<< overload template for member type CC<T>::Element
template<class T>
ostream& operator<<(ostream& os, const typename CC<T>::Element& elm) {
    return os << elm.val1 << "/" << elm.val2;
}

template<class T>
class CC
{
public:
    struct Element {    // type member
        int val1;
        int val2;
    };

    template<typename U>
    friend ostream& operator<<(ostream& os, const typename CC<U>::Element& elm);
};

int main() {
    CC<int>::Element elm{0,0};
    cout << elm << endl;     // does not compile due to this!
}

2 个答案:

答案 0 :(得分:9)

模板参数不能从嵌套实体中推导出来(简短说明:不同模板实例化的类型可能是seame)。即,声明

template<typename U>
ostream& operator<<(ostream& os, const typename CC<U>::Element& elm);

是否永远不会考虑friend,因为无法推断出类型U。您可以通过将friend运算符设为非模板来解决问题:

// ...
friend ostream& operator<<(ostream& os, const Element& elm) { ... }
// or
friend ostream& operator<<(ostream& os, const CC<T>::Element& elm) { ... }
// ...

但是,该功能需要在其声明中实施。

答案 1 :(得分:3)

您的问题在于以下代码

 ostream& operator<<(ostream& os, const typename CC<T>::Element& elm) {

Element位于非推断的上下文中。因此,无法推导出模板参数。而且由于使用显式模板参数调用operator<<会非常难看(如果可能的话),我建议更改整体编码模式。

例如,您可以将elm作为推导出的模板参数,例如

template<typename E>
friend ostream& operator<<(ostream& os, const E& elm);

而不是使用专门的结构从E中提取实际的U