我试图让我的头围绕元组(感谢@litb),他们使用的常见建议是返回> 1值的函数.
这是我通常使用结构的东西,在这种情况下我无法理解元组的优点 - 对于最终的懒惰来说,这似乎是一种容易出错的方法.
借用一个例子,我会用它
struct divide_result { int quotient; int remainder; };
使用元组,你会有
typedef boost::tupledivide_result;
但是如果你没有阅读你正在调用的函数的代码(或者评论,如果你足够愚蠢地信任它们),你就不知道哪个int是商,反之亦然.看起来很像......
struct divide_result { int results[2]; // 0 is quotient, 1 is remainder, I think };
......这不会让我满怀信心.
那么,什么是元组在该补偿的模糊性结构的优势是什么?
我想我同意你的观点,即什么位置的问题对应于什么变量会引起混乱.但我认为有两个方面.一个是呼叫方,另一个是被叫方:
int remainder; int quotient; tie(quotient, remainder) = div(10, 3);
我认为我们得到的结果非常清楚,但如果你必须一次返回更多的值,它会变得混乱.一旦调用者的程序员查阅了文档div
,他就会知道什么位置是什么,并且可以编写有效的代码.根据经验,我会说不会一次返回超过4个值.对于任何事情,更喜欢结构.
当然也可以使用输出参数:
int remainder; int quotient; div(10, 3, "ient, &remainder);
现在我认为这说明了元组如何比输出参数更好.我们将输入div
与输出混合在一起,但没有获得任何优势.更糟糕的是,我们让该代码的读者对可能的实际回报价值产生怀疑div
.当输出参数有用时,有很多很好的例子.在我看来,只有当你没有其他方法时才应该使用它们,因为返回值已经被采用并且不能更改为元组或结构.operator>>
在使用输出参数的位置上是一个很好的示例,因为返回值已经为流保留,因此您可以链接operator>>
调用.如果你不使用运算符,并且上下文不清楚,我建议你使用指针,在调用方面发信号通知对象实际上用作输出参数,以及适当的注释.
第三种选择是使用结构:
div_result d = div(10, 3);
我认为,肯定赢得该奖项清晰.但请注意,您仍然需要访问该结构中的结果,并且结果不会在表上"裸露",因为输出参数和使用的元组就是这种情况tie
.
我认为现在的一个重点是尽可能使一切尽可能通用.所以,假设你有一个可以打印出元组的函数.你可以这样做
cout << div(10, 3);
并显示您的结果.我认为,另一方面,元组显然因其多样性而获胜.使用div_result执行此操作时,需要重载operator <<,或者需要单独输出每个成员.
另一种选择是使用Boost Fusion地图(代码未经测试):
struct quotient; struct remainder; using boost::fusion::map; using boost::fusion::pair; typedef map< pair< quotient, int >, pair< remainder, int > > div_result;
您可以相对直观地访问结果:
using boost::fusion::at_key; res = div(x, y); int q = at_key(res); int r = at_key (res);
还有其他优点,例如迭代地图字段等的能力等.有关更多信息,请参阅doco.
使用元组,你可以使用tie
,这有时非常有用:std::tr1::tie (quotient, remainder) = do_division ();
.结构不是那么容易的.其次,在使用模板代码时,有时更容易依赖对,而不是为结构类型添加另一个typedef.
如果类型不同,那么一对/元组实际上并不比结构差.例如pair
,假设int是读取的字节数,bool是eof是否被命中.在这种情况下添加一个结构对我来说似乎有些过分,特别是因为这里没有歧义.