首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要特定的指令集来解决两类构造函数之间的冲突(其中一种是使用std::initializer_list)。

需要特定的指令集来解决两类构造函数之间的冲突(其中一种是使用std::initializer_list)。
EN

Stack Overflow用户
提问于 2022-08-21 13:07:21
回答 1查看 34关注 0票数 0

一个类(dLinkedList)需要有不同的代码:请不要建议使用STL容器!

代码语言:javascript
复制
explicit dLinkedList(const int value);
dLinkedList(const dLinkedList &rhs);
explicit dLinkedList(size_t numberOfNode, int initializationValue);
dLinkedList(const std::initializer_list<int> &arg);

然而,使用initializer_list的c-tor似乎不起作用.例如,如果我们像这样构造一个类:

代码语言:javascript
复制
dLinkedList test1 {10, 108}; // intention is to create 10 elements of 108 value each

但是我的问题是--基于这些论点--这个c-tor很可能被认为是initializer_list的一个。我该如何解决这场冲突?

最后两个构造函数的实现和类dLinkedList的结构如下:

代码语言:javascript
复制
class dLinkedList
{
public:

    //constructors will go here
    explicit dLinkedList(const int value)
    {
        createFirstNode(value);
        nodeCount = new size_t;
        updateNodeCount();
    }
    
    dLinkedList(const dLinkedList &rhs)
    {
        Node *temp = rhs.head;

        createFirstNode(temp->data);
        temp = temp->next;
        while(temp)
        {
            push_back(temp->data);
            temp = temp->next;
        }
        
        nodeCount = new size_t;
        updateNodeCount();
    }
    
    explicit dLinkedList(size_t numberOfNode, int initializationValue)
    {
        createFirstNode(initializationValue);
        for(size_t i = 1; i < numberOfNode; ++i)
            push_back(initializationValue);
        
        nodeCount = new size_t;
        updateNodeCount();
    }
    
    /* constructor with std::initializer_list is not working!!
    dLinkedList(const std::initializer_list<int> &arg)
    {
        std::cout << "\n Here\t";
        if(arg.size() == 0) dLinkedList(1);
        else
        {
            for(auto it = arg.begin() + 1; it != arg.end(); ++it)
            {
                push_back(*it);
            }
            
            nodeCount = new size_t;
            updateNodeCount();
        }
    }*/

    //class destructor will go here
    ~dLinkedList()
    {
        clear();
        delete nodeCount;
        nodeCount = nullptr;
    }

    //member functions will go here
    void push_back(int);                    // will attach a new node at the end of the list
    void push_front(int);                   // will insert a new node at the beginning of the list
    bool insertNode(int, int, bool, bool);  // will insert a new node after the existing node (true = first occurrence from the head with value int OTHERWISE if false, then from the tail.)
    bool deleteNode(int, bool);             // will delete the existing node (true = first occurrence from the head with value int OTHERWISE if false, then from the tail.)
    void pop_back();                         // will delete the last node in the list
    void pop_front();                       // will delete the first node in the list
    size_t size();                          // will return the number of nodes/elements - experimental feature
    void printList(bool);                   // will print the values of the data - (true for ordered list, false for reverse ordered list)
    void swap(dLinkedList &rhs);             // will swap this linked-list with rhs

    //operator overloading go here
    dLinkedList& operator = (const dLinkedList &rhs);
    dLinkedList& operator + (const dLinkedList &rhs);
    dLinkedList& operator += (const dLinkedList &rhs);
    dLinkedList& operator >> (const size_t numberOfNodes);
    dLinkedList& operator << (const dLinkedList &rhs);

private:
    //defining the double linked-list structure
    struct Node
    {
        int data; //this is a generic place holder - will be replaced later with some actual data-structures
        Node *next;
        Node *previous;

        explicit Node(int x) : data(x), next(nullptr), previous(nullptr) {}
    };

    //member functions go here
    void createFirstNode(int val);  //will create the first node when the list is empty
    void clear();  // will be called when class destructor is called
    void updateNodeCount(); // keeps the nodeCount variable up-to-date
    bool empty(); // returns true if the list is empty

    //some experimental utility functions for internal use
    void ectomizeAndClip(Node*);
    Node *detectData(int, bool);
    void insertBefore(Node*, int);
    void insertAfter(Node*, int);

    //member variables go here
    Node *head {nullptr};
    Node *tail {nullptr};
    size_t *nodeCount {nullptr}; //experimental feature
    
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-21 18:13:14

你不需要做任何事情来“解决冲突”。语言为您做这件事;在表单中初始化

代码语言:javascript
复制
dLinkedList test1 {10, 108};

如果可能的话,将始终调用initializer_list构造函数,只有在没有可行的initializer_list构造函数候选时,才会返回到非initializer_list构造函数。

问题是,潜在冲突的解决并没有产生你想要的结果。您希望它的解决有利于两个元素的构造函数。

只有当initializer_list构造函数有两个元素时,才有可能通过将该构造函数委托给另一个函数来模拟所需的内容:

代码语言:javascript
复制
explicit dLinkedList(size_t numberOfNode, int initializationValue) {
    initialize(numberOfNode, initializationValue);
}
dLinkedList(const std::initializer_list<int> &arg) {
    if (arg.size() == 2) {
        initialize(arg[0], arg[1]);
        return;
    }
    // otherwise: initialize the list using the values in `arg`
}
private:
void initialize(size_t numberOfNode, int initializationValue) {
    // create `numberOfNode` nodes with value `initializationValue`
}

但是,我强烈建议您不要这样做,因为如果以下三个声明的含义不相似,用户将非常困惑:

代码语言:javascript
复制
dLinkedList test1 {1};
dLinkedList test2 {2, 3};
dLinkedList test3 {4, 5, 6};

实际上,将节点数作为第一个参数,并将初始化这些节点的值作为第二个参数的构造函数通常是个坏主意。当用户忘记哪个参数是哪个参数时,它将导致错误。

更好的方法是创建一个具有所需节点数和期望初始值作为成员的struct

代码语言:javascript
复制
struct dLinkedListInit {
    int numberOfNodes;
    int initialValue;
};
explicit dLinkedList(dLinkedListInit i) {
    // ...
}

使用C++20指定的初始化器,此构造函数可用于以下步骤:

代码语言:javascript
复制
dLinkedList l({.numberOfNodes = 10, .initialValue = 108});

此外,由于初始化程序列表构造函数可以提供相同的功能,所以请删除构造函数explicit dLinkedList(const int value);。让用户显式地写出大括号是很好的,这样可以清楚地看到大括号中的值被解释为元素值。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73434700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档