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

C++ template how to overloading operator and accessing private property

本文关键字:运算符 访问 私有财产 重载 何重载 C++      更新时间:2023-10-16

我目前正在尝试实现一个简单的基于模板的链表,该链表在 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(;"。错误:"元素"之前的预期类型说明符

如果我把它放到类本身中,我无法访问 list.head,即使它是朋友。

你应该只在类模板定义之前(在前向声明之后(保留函数模板的声明,以告诉编译器在 friend 声明中指定的operator+=是一个模板。然后稍后定义它。例如

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

附注:

  1. 不要用名称命名参数 list ,这与类模板的名称冲突 list

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

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