返回函数内的2个值

returning 2 values within a function

本文关键字:2个值 函数 返回      更新时间:2023-10-16

我试图在读取文件时返回值(即行和列),由于我将在多个文件中读取,并从每个文件中获得相同的变量,我认为编写一个函数比复制和粘贴重复的代码更好。

无论如何,我正在尝试返回2个值并使用它们,请参阅下面的代码:

#include <iostream>
#include <fstream>
using namespace std;
int r(string fn);
int main()
{
    int a, b = r("input_a.txt");
    cout << "a --- " << a << endl;
    cout << "b --- " << b << endl;
}
int r(string fn)
{
    ifstream fin01;
    string file = fn;
    fin01.open(file.c_str());
    ...
    ...
    ...
    // Suppose I should be getting 2 for 'rows' and 3 for 'cols'
    return rows, cols;
}

我得到了0x7fff670778ec0x7fff670778e8作为我的输出。。。

有指针吗?

不能从声明为具有单个int作为返回类型的函数返回两个值:

int r(string fn){
    /*...*/
    return rows,cols;  // <-- this is not correct
}

此外,您调用此函数的方式并不像您预期的那样:

int a, b = r("input_a.txt");

这声明了两个整数,并用函数的返回值初始化第二个整数,但第一个未初始化(有关逗号运算符的更多解释,请参阅TerraPass答案)。

你基本上有两种选择。第一个选项是将引用传递给函数,函数将结果分配给这些引用:

void r(string fn, int& rows,int& cols) {
    /*...*/
    rows = x;
    cols = y;
}

你这样称呼它:

int a,b;
r("someString",a,b);

但是,通过这种方式,调用者必须"准备"那些返回值。Imho使用返回值来返回函数的结果更方便(听起来合乎逻辑,不是吗?)。要做到这一点,您只需要定义一个封装两个整数的类型:

struct RowAndCol { int row;int col; };
RowAndCol r(string fn) {
    /*...*/
    RowAndCol result;
    result.row = x;
    result.col = y;
    return result;
}

并这样称呼它:

RowAndCol rc = r("someString");

请注意,您也可以使用std::pair<int,int>,而不是定义自定义结构(例如,参见molbdnilos答案)。然而,IMHO只要你确切地知道这对中包含什么,最好给它一个合理的名称(例如RowAndCol),而不是使用裸露的std::pair<int,int>。这也将在以后需要向结构添加更多方法的情况下对您有所帮助(例如,您可能希望重载结构的std::ostream& operator<<以将其打印在屏幕上)。

PS:实际上,你的输出看起来并不是由你显示的代码产生的。这些是一些内存地址,但在您的代码中既没有指针,也没有运算符的地址。

我想你已经习惯了Python(我看了一下你的配置文件),但逗号在C++中不会创建一对。

(你可能没有想过,但你也只能从Python函数返回一个值。如果你"返回两个值",你就返回了一个对。)

幸运的是,标准库中有元组。

#include <iostream>
#include <fstream>
#include <utility>

std::pair<int,int> r(std::string fn);
int main()
{
    std::pair<int, int> result = r("input_a.txt");
    cout << "a --- " << result.first << endl;
    cout << "b --- " << result.second << endl;
// Or,
    int a = 0;
    int b = 0;
    std::tie(a, b) = r("input_a.txt");
    cout << "a --- " << a << endl;
    cout << "b --- " << b << endl;

}
std::pair<int, int> r(std::string fn)
{
    std::ifstream fin01(fn);
    // ...
    return std::make_pair(rows, cols);
}
C++中的函数不能通过return语句返回其返回类型的多个值。
int a, b = r("input_a.txt");
...
return rows, cols;

这两条线并不像你想象的那样。

线路int a, b = r("input_a.txt");相当于:

int a;
int b = r("input_a.txt");

也就是说,声明变量ab,并将b初始化为r("input_a.txt")的返回值,而a保持未初始化状态。

线路return rows, cols;相当于:

rows;
return cols;

和是逗号运算符的一个示例,它计算其左操作数(在您的情况下为rows),丢弃结果,然后计算其右操作数(在此情况下为cols),并返回此计算的结果。因此,实际上,函数r()和现在一样,总是返回一个值cols


如果需要从一个函数返回多个值,则应考虑接受其他参数作为非常量引用,以便将结果值存储到其中,或者将函数的返回类型更改为某个struct,该类型将包含要返回的所有值。你可以在@tobi303的回答中找到这两种方法的一个例子。