如何修复尝试在 cpp 中绑定 ':basic_string<char> >&' 和 ':basic_string<char> >' 的错误?

How to fix an error of trying to bind ':basic_string<char> >&' and ':basic_string<char> >' in cpp?

我的代码无法编译,我不知道如何修复它。看起来问题可能出在“=”运算符上,但我不确定。我试图在排序列表的元素上应用给定函数以获得不同的排序列表,但它说我使用的参数与预期的不同。 我的代码看起来像-

#include <iostream>
#include <cstring>
#include <string>
#include <functional>

#include "dummy.h"
using namespace std;

#ifndef SORT_H
#define SORT_H

template <class T>
class LinkedList {
    struct Node {
        Node(const T &in) : data(in) {}
        T data;
        Node * next;
    };

    class Iterator
    {
        Node *m_ptr;              // pointer to current node in the list
    public:
        Iterator(Node * node) {
            m_ptr = node;
        }
        Iterator& operator ++ () {
            m_ptr = m_ptr -> next();
            return *this;
        }
        Iterator operator ++ (T) {
            Iterator temp(*this);
            m_ptr = m_ptr -> next();
            return temp;
        }
        bool operator == (const Iterator other) const {
            return m_ptr == other.m_ptr;
        }
        bool operator != (const Iterator other) const {
            return m_ptr != other.m_ptr;
        }
        T& operator * () {
            return m_ptr -> data();
        }
        operator bool() {
            return m_ptr != 0;
        }
    };

    Node * head;

    bool is_in_list(T value){
        Node * curr = head;
        while(curr != nullptr) {
            if (curr->data == value){
                return true;
            } else {
                curr = curr->next;
            }
        }
        return false;
    }


public:
    LinkedList() {
        head = nullptr;
    }
    LinkedList(T value) {
        head = new Node(value);
//        head -> data = value;
//        head -> next = nullptr;
    }

    ~LinkedList() {
        while(head != nullptr) {
            Node * curr = head -> next;
            delete head;
            head = curr;
        }
    }

    LinkedList operator = (LinkedList &list) {
        LinkedList<T> new_list(list);
        return new_list;
    }

    Node * nodeCopy(Node * head) {
        if (head == nullptr) {
            return nullptr;
        }
        Node * copied_node = new Node(head -> data);
        copied_node -> data = head -> data;
        copied_node -> next = nodeCopy(head -> next);
        return copied_node;
    }

    LinkedList(LinkedList &list){
        head = nodeCopy(list.head);
    }


    template<typename B>
    LinkedList filter(LinkedList &list, B pred) {
        LinkedList <T> new_list(list);
        Node * curr = list.head;
        while (curr) {
            if (!(pred(curr -> data))) {
                new_list.remove(curr -> data);
            }
            curr = curr -> next;
        }
        std::cout << "Getting out of filter" << std::endl;
        return new_list;
    }

    template<typename A>
    LinkedList apply(A func) {
        LinkedList <T> new_list;
        Node * curr = head;
        while (curr) {
            new_list.insert(func(curr -> data));
            std::cout << "Putting into new list: " << func(curr -> data) << std::endl;
            curr = curr -> next;
        }
        std::cout << "Getting out of apply" << std::endl;
        return new_list;
    }

    int length() {
//        std::cout << "DEBUG length 1" << std::endl;
        int counter = 0;
        Node * tmp = head;
//        std::cout << "DEBUG length 2" << std::endl;
        while( tmp != nullptr ) {
//            std::cout << "DEBUG length 3" << std::endl;
            counter++;
            tmp = tmp -> next;
        }
        return counter;
    }

    void insert(T value) {
        // Add first node
        if (head == nullptr) {
            std::cout << "Add first node" << std::endl;
            head = new Node(value);
            head->next = nullptr;
            return;
        }

        Node *curr = head;
        // check if should be new head (when new value smaller than current head) -> add new head
        if (value <= head->data) {
            // add new head
            std::cout << "add new head" << std::endl;
            Node * new_head = new Node(value);
            new_head -> next = head;
            head = new_head;
            return;
        }

        while (curr != nullptr) {
            if (curr->next == nullptr && value >= curr->data) {
                // add new tail
                std::cout << "add new tail" << std::endl;
                Node * new_node = new Node(value);
                curr -> next = new_node;
                new_node -> next = nullptr;
                return;
            } else if (value >= curr->data && value <= curr->next->data) {
                // add new node between those two
                std::cout << "add new node between those two" << std::endl;
                Node * new_node = new Node(value);
                Node * temp_ptr = curr -> next;
                curr -> next = new_node;
                new_node -> next = temp_ptr;
                return;
            } else {
                curr = curr->next;
            }
        }
    }

    void remove(T value) {
        // TODO: Check if delete all accurancies
        if (!is_in_list(value)){
            return;
        }

        // handle the head
        if (head->data == value) {
            if (head->next != nullptr) {
                // head is not single node
                Node * temp_ptr = head->next;
                delete head;
                head = temp_ptr;
                return;
            } else {
                // head is single node
                delete head;
                head = nullptr;
                return;
            }
        }

        Node * curr = head;
        Node * prev = head;
        while (curr != nullptr){
            if (curr -> data == value){
                // as we are already handled the head case,
                // at this point we know that curr != head.
                prev->next = curr->next;
                delete curr;
                return;
            } else {
                prev=curr;
                curr=curr->next;
            }
        }

    }

    void print() {
        Node * curr = head;
        while (curr != nullptr) {
            cout << curr -> data << endl;
            curr = curr -> next;
        }
    }

    Iterator begin() {
        return head;
    }
    Iterator end() {
        return Iterator(nullptr);
    }
};


#endif

主要是这样的-

#include <iostream>
#include "sortedList.h"
#include "dummy.h"

bool func(Dummy num) {
    int number = num.get();
    if (number % 2 != 0) {
        return false;
    }
    return true;
}

string getLen(string str)
{
    return std::to_string(str.length());
}

int main() {
    std::cout << "Hello, World!" << std::endl;

    LinkedList <string> myList;
    myList.insert("yosi");
    myList.insert("Rikki");
    myList.insert("Pavel <3");
    cout << "Now printing myList" << endl;
    myList.print();

    LinkedList<string> new_list;
    new_list = myList.apply(getLen);
    cout << "Now printing new_list" << endl;
    new_list.print();

    return 0;
}

我得到的错误是-

====================[ Build | exe_name | Debug ]================================
"C:\Program Files\JetBrains\CLion 2021.1.1\bin\cmake\win\bin\cmake.exe" --build C:\Users\User\CLionProjects\ex2.2\cmake-build-debug --target exe_name -- -j 3
Scanning dependencies of target exe_name
[ 33%] Building CXX object CMakeFiles/exe_name.dir/main.cpp.obj
[ 66%] Building CXX object CMakeFiles/exe_name.dir/sortedList.cpp.obj
C:\Users\User\CLionProjects\ex2.2\main.cpp: In function 'int main()':
C:\Users\User\CLionProjects\ex2.2\main.cpp:101:28: error: cannot bind non-const lvalue reference of type 'LinkedList<std::__cxx11::basic_string<char> >&' to an rvalue of type 'LinkedList<std::__cxx11::basic_string<char> >'
     new_list = myList.apply(getLen);
                ~~~~~~~~~~~~^~~~~~~~
In file included from C:\Users\User\CLionProjects\ex2.2\main.cpp:2:
C:\Users\User\CLionProjects\ex2.2\sortedList.h:83:16: note:   initializing argument 1 of 'LinkedList<T> LinkedList<T>::operator=(LinkedList<T>&) [with T = std::__cxx11::basic_string<char>]'
     LinkedList operator = (LinkedList &list) {
                ^~~~~~~~
mingw32-make.exe[3]: *** [CMakeFiles\exe_name.dir\build.make:81: CMakeFiles/exe_name.dir/main.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs....
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:94: CMakeFiles/exe_name.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:101: CMakeFiles/exe_name.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:136: exe_name] Error 2

我该如何解决这个问题?

你的 copy assignment operator 给你带来了麻烦。

LinkedList apply(A func)函数returns(按值)一个LinkedList,然后在这一行依次使用,在main.cpp...

new_list = myList.apply(getLen);

... 将 LinkedList 的新创建实例复制分配给 new_list,( 上方实例化)。

因此,您需要将适当的逻辑合并到您的 LinkedList::operator= 中,以正确处理分配的内存并引入所需的逻辑。

考虑 and few other resources, I would suggest you to stick to the copy-and-swap成语后,像这样:

LinkedList& operator = (LinkedList list) {
    std::swap(list.head, head); // if you don't define your own swap
    return *this;
}

为此,您还需要修改复制构造函数,如下所示:

LinkedList(const LinkedList &list){
    head = nodeCopy(list.head);
}

结果示例输出:

Hello, World!
Add first node
add new head
add new head
Now printing myList
Pavel <3
Rikki
yosi
Add first node
Putting into new list: 8
add new head
Putting into new list: 5
add new head
Putting into new list: 4
Getting out of apply
Now printing new_list
4
5
8