C ++模板如何重载运算符和访问私有属性

时间:2017-11-15 00:18:36

标签: c++ templates overloading operator-keyword friend

我目前正在尝试实现一个简单的基于模板的链表,它在C ++ 11中采用通用键/值对。元素应该由+ =运算符添加到列表中。代码如下所示:

列表

// Forward declarations
template<typename K, typename V>
class list;

template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &list, const std::tuple<K, V> ele) {
    if (!list.head) {
        // list is empty
        list.head = new element(ele, nullptr);
    }

    return list;
};

// Class definition
template<typename K, typename V>
class list {
private:
    struct element {
        const K key;
        const V value;
        element *next;

        element(const std::tuple<K, V> tuple, element *ele) :
                key(std::get<0>(tuple)),
                value(std::get<1>(tuple)),
                next(ele) { }
    };

    element *head = nullptr;

public:
    friend list<K, V> &operator+=<>(list<K, V> &list, const std::tuple<K, V> ele);
};

我无法编译。我是否必须将运算符的实现放入前向声明或类本身?如果我把它放在前向声明中,就像在片段中一样,我似乎无法使用“list.head = new element(ele,nullptr);”​​。错误:'element'之前的预期类型说明符

如果我将它放入课堂本身,我就无法访问list.head,即使它是朋友。

1 个答案:

答案 0 :(得分:2)

您应该在类模板定义之前(在前向声明之后)保留函数模板的声明,以告诉编译器在友元声明中指定的operator+=是模板。然后再定义它。 e.g。

// Forward declarations
template<typename K, typename V>
class list;

// declaration of function template
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &l, const std::tuple<K, V> ele);

// Class definition
template<typename K, typename V>
class list {
    ...
    friend list<K, V> &operator+=<>(list<K, V> &l, const std::tuple<K, V> ele);
};

// definition of function template
template<typename K, typename V>
list<K, V> &operator+=(list<K, V> &l, const std::tuple<K, V> ele) {
    if (!l.head) {
        // list is empty
        l.head = new typename list<K, V>::element(ele, nullptr);
    }

    return l;
}

PS:

  1. 请勿使用名称list命名参数,该名称与类模板list的名称冲突。

  2. element是一个嵌套结构,在operator+=中,您应该像typename list<K, V>::element一样指定它。

  3. 使用名称list(与std::list相同)不是一个好主意。

  4. LIVE