friend 模板函数导致未定义符号错误

问题描述 投票:0回答:1

背景:

该程序应该有一个单个链接列表的模板,您可以在其中通过键查找信息。我的意思是实现一个分割函数,它接受一个源序列,在“start”索引处开始分割它,然后将“step1”数量的项目发送到result1,然后将“step2”数量的项目发送到result2,依此类推,直到出现用完源中的项目来完成下一步数量,然后源中的其余项目将被赋予当前序列。

我不明白为什么会出现这个错误:

ld:未定义的符号:

split(Sequence const&, int, Sequence&, int, int, Sequence&, int, int),引用自:

_main 在 main-123c17.o 中

clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

对于此代码:

#include <iostream>
#include <cstdlib>  
#include <ctime>    
using namespace std;

template <typename Key, typename Info>
// a template for a single linked list in which you may find an element's info with a key (keys are not unique)(will implement find later)
class Sequence {
private:
    struct Node {
        Key key;
        Info info;
        Node* next;
        Node(Key k, Info i) : key(k), info(i), next(nullptr) {}
    }; 
    Node* head;
    int length;

public:
    Sequence() : head(nullptr), length(0) {}

    void push(Key k, Info i) {
        // adds a node to the end of the sequence
        Node* newNode = new Node(k, i);
        if ( !head) {
            head = newNode;
        } else {
            Node* temp = head;
            while (temp->next) {
                temp = temp->next;
            }
            temp->next = newNode;
        }
        length++;
    }

    //copy constructor
    Sequence(const Sequence<Key, Info>& other) : head(nullptr), length(0) {
        Node* current = other.head;
        while (current) {
            push(current->key, current->info);
            current = current->next;
        }
    }

    //destructor
    ~Sequence() {
        while (head) {
            Node* temp = head;
            head = head->next;
            delete temp;
        }
    }

    //printing all info from a sequence
    void print(){
        Node* current = head;
        while (current) {
            cout << "(" << current->info << ") -> ";
            current = current->next;
        }
        cout << endl;
    }

    friend void split(const Sequence<Key, Info>& source, int start,
              Sequence<Key, Info>& result1, int step1, int length1,
              Sequence<Key, Info>& result2, int step2, int length2);
};


template <typename Key, typename Info>
void split(const Sequence<Key, Info>& source, int start,
           Sequence<Key, Info>& result1, int step1, int length1,
           Sequence<Key, Info>& result2, int step2, int length2) {

    typename Sequence<Key, Info>::Node* current = source.head;
    int index = 0;

    while (index < start) {
        current = current->next;
        index++;
    }

    bool toResult1 = true; 
    while (current &&(length1 > 0 || length2 > 0)){
        int steps = toResult1 ? step1 : step2;
        int& currentLength = toResult1 ? length1 : length2;
        int movingLength;

        Sequence<Key, Info>& targetSequence = toResult1 ? result1 : result2;
        int targetLength = toResult1 ? length1 : length2;

        for (int i = 0; i < steps && current && currentLength > 0; i++) {
            targetSequence.push(current->key, current->info);
            current = current->next;
            currentLength--;
            targetLength++;
        }
        if (targetLength + steps <= currentLength ){
            toResult1 = !toResult1; //once the steps are done, move onto the next res list
        }else {
            for (int i = 0; i <currentLength; i++) {
            targetSequence.push(current->key, current->info);
            current = current->next;
            currentLength--;
            }
        }
    }
}


int main(){
    
    Sequence<char, int> source;
    Sequence<char, int> result1;
    Sequence<char, int> result2;

    source.push('A', 1);
    source.push('B', 2);
    source.push('C', 3);
    source.push('D', 4);
    source.push('E', 5);
    source.push('F', 6);
    source.push('G', 7);
    source.push('H', 8);
    
    cout << "Source:";
    source.print();

    split(source, 2, result1, 2, 3, result2, 1, 3);

    cout << "Result 1:";
    result1.print();
    cout << endl;
    cout << "Result 2:";
    result2.print();
    cout << endl;

    return 0;

}

split是类的友元,有一个main函数。我不知道要修复什么,因为这就是我所得到的。这是我忽略的简单问题还是逻辑缺陷或其他问题......?

c++ templates class-template
1个回答
0
投票

您没有正确声明您的好友功能。

在类定义之前,需要进行以下前向声明:

template <typename Key, typename Info> class Sequence;

template <typename Key, typename Info>
void split(const Sequence<Key, Info>& source, int start,
    Sequence<Key, Info>& result1, int step1, int length1,
    Sequence<Key, Info>& result2, int step2, int length2);

那么,

friend
函数必须使用模板参数进行声明,否则编译器会认为你打算使用
split
非模板函数,而这显然是不存在的。

friend void split<Key, Info>(const Sequence<Key, Info>& source, int start,
    Sequence<Key, Info>& result1, int step1, int length1,
    Sequence<Key, Info>& result2, int step2, int length2);
© www.soinside.com 2019 - 2024. All rights reserved.