returning 2 values within a function

时间:2016-04-15 11:08:19

标签: c++

I am trying to return values (namely rows and columns) upon a file read, and since I will be reading in multiple files and getting the same variables from each file, I thought it will be better for me to write a function rather than copying and pasting duplicate codes.

Anyway, I am trying to return 2 values and to use them too, please see my code below:

#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;
}

I got 0x7fff670778ec and 0x7fff670778e8 for my output instead...

Any pointers?

3 个答案:

答案 0 :(得分:6)

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

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

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

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

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

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

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 answer)。但是,恕我直言,只要您确切知道对中包含的内容,最好给它一个合理的名称(例如RowAndCol),而不是使用裸std::pair<int,int>。如果您以后需要向结构中添加更多方法(例如,您可能希望重载结构的std::ostream& operator<<以在屏幕上打印它),这也可以帮助您。

PS:实际上你的输出看起来不像是你所展示的代码产生的。这些是一些内存地址,但在你的代码中既没有指针也没有地址操作符。

答案 1 :(得分:2)

我猜你已经习惯了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);
}

答案 2 :(得分:1)

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;

...并且是comma operator的示例,它评估其左操作数(在您的情况下为rows),丢弃结果,然后计算其右操作数(在您的情况下,{{ 1}})并返回此评估的结果。因此,实际上,您现在的函数cols始终返回单个值r()

如果需要从函数返回多个值,则应考虑接受其他参数作为非const引用,以便将结果值存储到或将函数的返回类型更改为某些cols ,它将包含您要返回的所有值。你可以在@ tobi303&#39; answer中找到这两种方法的例子。