如何在带有参数折叠的可变参数函数中传递不同的数据类型?

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

制作一个链接列表库,我想传递多个值以便更容易地附加项目,因此我创建了一些可变参数函数,这些函数在使用 int 值进行测试时效果很好,但不适用于其他数据类型。

我的链表结构:

template<typename s_data_type>
struct linked_list {
private:
    typedef _node<s_data_type> node;
    typedef s_data_type dt;
    int _size{};
    node* head = nullptr;
    node* last = nullptr;

    //Methods, Constructors, etc...
};

节点结构:

template<typename data_type>
struct _node {
    data_type data{};
    _node<data_type>* link = nullptr;
    _node(data_type value) : data(value) {}
};

现在,为了附加列表,我有一个附加函数:

void append(const dt value) {
    if (this->head == nullptr) {
        head = new node(value);
        last = head;
    }
    else {
        last->link = new node(value);
        last = last->link;
    }
    _size++;
}

对于测试的数据类型

Float
Int
String
,以及可变参数函数,只要初始化的 LL 是
int
类型,它本身就可以正常工作。

可变参数函数:

template<typename ...Args> linked_list(Args ...arg) {
 (append(arg), ...); 
}
template<typename ...Args> void append(Args ...arg) {
  (append(arg), ...);
}

第一个,构造函数,工作得很好,A+,不会抛出任何分段错误,它是重载的附加函数,它会抛出分段错误,但它都适用于 Int 类型,这是因为我猜它是模板的结构类类型?

LL int 的主要功能:

linked_list<int> list(1, 2, 3);
list.append(4, 5);
list.print();

输出:

{ 1 2 3 4 5 }
1 2 3 4 5

但是对于字符串:

    linked_list<string> list("123", "Such a", "Why does this work");
    list.print();
    list.append("hmm");
    list.append("wooowowow", "Please Work");
    list.append("No");
    println();
    list.print();

给我一个分段错误,即使在调查之后,我也无法查明原因? 分段错误

发生异常:分段错误

现在我研究了参数折叠、一元、带有折叠参数的二进制东西,阅读了一些文档和论坛,我想出了以下内容,我几乎无法理解它为什么起作用。

template<typename ...args> void append(dt val, args ...arg) {
    (append(val), ((arg), ...));
}

对于它生成的 String LL 初始化:

{ 123 Such a Why does this work }
{ 123 Such a Why does this work hmm wooowowow No }

它跳过“请工作”字符串,我不知道为什么,甚至不知道它是如何工作的,但是,是的,它几乎可以工作,对于 Int 部分,同样,不附加 5到法学硕士。

{ 1 2 3 4 }
1 2 3 4

如何制作一个可以将参数传递给另一个函数的可变参数函数?

我的期望是:

对于字符串:

{ 123 Such a Why does this work }
{ 123 Such a Why does this work hmm wooowowow Please Work No }

对于国际:

{ 1 2 3 4 5 }
1 2 3 4 5
c++ segmentation-fault c++17 variadic-templates variadic
1个回答
0
投票

将 std::cout 插入到每个函数后,它会打印很多行,我发现你的代码崩溃了:

list.append_values("hmm");

可变参数追加函数是无限递归的,您需要重命名其中一个追加函数。例如

#include <iostream>
#include <string>

template<typename data_type>
struct _node {
    data_type data{};
    _node<data_type>* link = nullptr;
    _node(data_type value) : data(value) {}
};

template<typename s_data_type>
struct linked_list {
private:
    typedef _node<s_data_type> node;
    typedef s_data_type dt;
    int _size{};
    node* head = nullptr;
    node* last = nullptr;

public:
    template<typename ...Args> linked_list(Args ...arg) {
        (append_value(arg), ...); 
    }

    void append_value(const dt value) {
        if (this->head == nullptr) {
            head = new node(value);
            last = head;
        }
        else {
            last->link = new node(value);
            last = last->link;
        }
        _size++;
    }

    template<typename ...Args> void append_values(Args ...arg) {
        (append_value(arg), ...);
    }

    void print() {
        node* current = head;
        while (current != nullptr) {
            std::cout << current->data << " -> ";
            current = current->link;
        }
        std::cout << "nullptr" << std::endl;
    }
};

void println() {
    std::cout << "\n";
}

int main() {
    linked_list<std::string> list("123", "Such a", "Why does this work");
    list.print();
    list.append_values("hmm"); // No more crash on this line
    list.append_values("wooowowow", "Please Work");
    list.append_values("No");
    println();
    list.print();

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.