C++在函数中创建std::list并通过参数返回

C++ Create std::list in function and return through arguments

本文关键字:参数 返回 list C++ 函数 创建 std      更新时间:2023-10-16

如何通过函数参数更正返回创建的std::list?现在,我试着这么做:

bool DatabaseHandler::tags(std::list<Tag> *tags)
{
    QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
    QSqlQueryModel model;
    model.setQuery(sql);
    if(model.lastError().type() != QSqlError::NoError) {
        log(sql);
        tags = NULL;
        return false;
    }
    const int count = model.rowCount();
    if(count > 0)
        tags = new std::list<Tag>(count);
    else
        tags = new std::list<Tag>();
//some code
    return true;
}

之后我可以使用它:

std::list<Tag> tags;
mDB->tags(&tags);

现在,我修复了我的功能:

bool DatabaseHandler::tags(std::list<Tag> **tags)
{
    QString sql = "SELECT * FROM " + Tag::TABLE_NAME + ";";
    QSqlQueryModel model;
    model.setQuery(sql);
    if(model.lastError().type() != QSqlError::NoError) {
        log(sql);
        *tags = NULL;
        return false;
    }
    const int count = model.rowCount();
    if(count > 0)
        *tags = new std::list<Tag>(count);
    else
        *tags = new std::list<Tag>();
    for(int i = 0; i < count; ++i) {
        auto record = model.record(i);
        Tag tag(record.value(Table::KEY_ID).toInt());
        (*tags)->push_back(tag);
    }
    return true;
}

虽然循环只执行2次迭代和空的子对象(如果我刚刚调用了它们的默认构造函数),但它可以工作,但列表返回大小为4。Tag类没有复制构造函数。

由于您传递了一个已经实例化的列表作为指向函数的指针,因此不需要创建另一个列表。从这个意义上说,你的问题很不清楚。我建议您阅读一些关于指针、引用和函数调用的一般知识。

http://www.cplusplus.com/doc/tutorial/pointers/http://www.cplusplus.com/doc/tutorial/functions/

更新:我仍然强烈建议你阅读上面提到的主题,因为你不知道这些基本点。无论如何,这就是你可能想要做的(尽管我建议使用引用,但这里是带指针的解决方案):

bool someFunc(std::list<Tag> **tags) {
    // by default null the output argument
    *tags = nullptr;
    if (error) {
        return false;
    }
    // dereference tags and assign it the address to a new instance of list<Tag>
    *tags = new std::list<Tag>();
    return true
}

std::list<Tag> *yourList;
if (someFunc(&yourList)) {
    // then yourList is valid
} else {
   // then you had an error and yourList == nullptr
}

然而,这不是惯用的C++。请阅读现代书籍或教程。

使用引用。

bool DatabaseHandler::tags(std::list<Tag>& tags);
std::list<Tag> tags;
mDB->tags(tags);

当然,您必须将所有的->更改为.。对函数中的引用执行的每个操作都将对调用它时使用的原始tags列表执行。

编辑:如果你想在函数中创建列表并返回它,你有几个选项。我认为,最接近的方法是只返回一个列表指针,如果函数失败,则返回nullptr

//beware, pseudocode ahead
std::list<Tag>* DatabaseHandler::tags() //return new list
{
    if (success)
        return new std::list<Tag>(...); //construct with whatever
    else
        return nullptr; //null pointer return, didn't work
}
std::list<Tag> tags* = mDB->tags();

您也可以让它返回一个空列表,这取决于您希望它如何工作。引用指针也可以用同样的方法。

    bool DatabaseHandler::tags(std::list<Tag>*&); //return true/false
    std::list<Tag>* tags;
    mDB->tags(tags); //tags will be set to point to a list if it worked