【问题标题】:C++ template how to overloading operator and accessing private propertyC ++模板如何重载运算符和访问私有属性
【发布时间】:2018-04-28 02:09:58
【问题描述】:

我目前正在尝试实现一个简单的基于模板的链表,该链表采用 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);
};

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

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

【问题讨论】:

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


    【解决方案1】:

    你应该在类模板定义之前(在前向声明之后)留下函数模板的声明,告诉编译器在朋友声明中指定的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;
    }
    

    PS:

    1. 不要将参数命名为list,与类模板名称list冲突。

    2. element 是一个嵌套结构,在operator+= 中你应该像typename list&lt;K, V&gt;::element 一样指定它。

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

    LIVE

    【讨论】:

    • 谢谢,这有帮助。但是为什么我需要一个前向声明和一个类中的声明呢?
    • @octavio 告诉编译器在friend声明中指定的operator+=是一个模板。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多