Boost::Tuples vs Structs 返回值

2022-01-20 00:00:00 tuples c++ boost-tuples

我正试图了解元组(感谢@litb),使用它们的常见建议是返回 > 1 值的函数.

I'm trying to get my head around tuples (thanks @litb), and the common suggestion for their use is for functions returning > 1 value.

这是我通常会使用结构的东西,在这种情况下我无法理解元组的优势 - 对于最终懒惰的人来说,这似乎是一种容易出错的方法.

This is something that I'd normally use a struct for , and I can't understand the advantages to tuples in this case - it seems an error-prone approach for the terminally lazy.

借用一个例子,我会用这个

struct divide_result {
    int quotient;
    int remainder;
};

使用元组,您将拥有

typedef boost::tuple<int, int> divide_result;

但是,如果不阅读您正在调用的函数的代码(或注释,如果您愚蠢到相信它们),您将不知道哪个 int 是商,反之亦然.好像有点……

But without reading the code of the function you're calling (or the comments, if you're dumb enough to trust them) you have no idea which int is quotient and vice-versa. It seems rather like...

struct divide_result {
    int results[2]; // 0 is quotient, 1 is remainder, I think
};

...这不会让我充满信心.

...which wouldn't fill me with confidence.

那么,元组相对于弥补歧义的结构的优势是什么?

So, what are the advantages of tuples over structs that compensate for the ambiguity?

推荐答案

元组

我想我同意你的观点,即什么位置对应什么变量的问题会引起混淆.但我认为有两个方面.一个是call-side,一个是callee-side:

int remainder; 
int quotient;
tie(quotient, remainder) = div(10, 3);

我认为我们得到的结果非常清楚,但如果您必须一次返回更多值,它可能会变得混乱.一旦调用者的程序员查阅了div的文档,他就会知道什么位置是什么,并且可以编写有效的代码.根据经验,我会说不要一次返回超过 4 个值.除此之外,更喜欢结构.

I think it's crystal clear what we got, but it can become confusing if you have to return more values at once. Once the caller's programmer has looked up the documentation of div, he will know what position is what, and can write effective code. As a rule of thumb, i would say not to return more than 4 values at once. For anything beyond, prefer a struct.

当然也可以使用输出参数:

Output parameters can be used too, of course:

int remainder; 
int quotient;
div(10, 3, &quotient, &remainder);

现在我认为这说明了元组如何优于输出参数.我们将 div 的输入与其输出混合在一起,但没有获得任何优势.更糟糕的是,我们让该代码的读者对 div 的 actual 返回值可能是什么感到怀疑.当输出参数有用时,有 个很好的例子.在我看来,只有在没有其他方法的情况下才应该使用它们,因为返回值已经被采用并且不能更改为元组或结构.operator>> 是使用输出参数的一个很好的例子,因为返回值已经为流保留,所以你可以链接 operator>> 调用.如果您与运算符无关,并且上下文不是很清楚,我建议您使用指针,在调用端发出信号表明该对象实际上用作输出参数,以及适当的注释.

Now i think that illustrates how tuples are better than output parameters. We have mixed the input of div with its output, while not gaining any advantage. Worse, we leave the reader of that code in doubt on what could be the actual return value of div be. There are wonderful examples when output parameters are useful. In my opinion, you should use them only when you've got no other way, because the return value is already taken and can't be changed to either a tuple or struct. operator>> is a good example on where you use output parameters, because the return value is already reserved for the stream, so you can chain operator>> calls. If you've not to do with operators, and the context is not crystal clear, i recommend you to use pointers, to signal at the call side that the object is actually used as an output parameter, in addition to comments where appropriate.

第三种选择是使用结构体:

The third option is to use a struct:

div_result d = div(10, 3);

我认为这肯定会因清晰而获奖.但请注意,您仍然必须访问该结构中的结果,并且结果不会裸露"在桌子上,因为输出参数和与 tie 一起使用的元组就是这种情况.

I think that definitely wins the award for clearness. But note you have still to access the result within that struct, and the result is not "laid bare" on the table, as it was the case for the output parameters and the tuple used with tie.

我认为这些天来的一个重点是让一切尽可能通用.所以,假设你有一个可以打印元组的函数.你可以这样做

I think a major point these days is to make everything as generic as possible. So, say you have got a function that can print out tuples. You can just do

cout << div(10, 3);

并显示您的结果.我认为另一方面,元组显然因其多功能性质而获胜.使用 div_result 执行此操作,您需要重载 operator<<,或者需要单独输出每个成员.

And have your result displayed. I think that tuples, on the other side, clearly win for their versatile nature. Doing that with div_result, you need to overload operator<<, or need to output each member separately.

相关文章