为什么在 C++ 中元组的使用不常见?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/855110/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 17:36:12  来源:igfitidea点击:

Why is the use of tuples in C++ not more common?

c++tuples

提问by Zifre

Why does nobody seem to use tuples in C++, either the Boost Tuple Libraryor the standard library for TR1? I have read a lot of C++ code, and very rarely do I see the use of tuples, but I often see lots of places where tuples would solve many problems (usually returning multiple values from functions).

为什么似乎没有人在 C++ 中使用元组,无论是Boost Tuple 库还是 TR1 的标准库?我读了很多 C++ 代码,很少看到元组的使用,但我经常看到很多地方可以用元组解决很多问题(通常从函数中返回多个值)。

Tuples allow you to do all kinds of cool things like this:

元组允许你做各种很酷的事情,比如:

tie(a,b) = make_tuple(b,a); //swap a and b

That is certainly better than this:

这当然比这更好:

temp=a;
a=b;
b=temp;

Of course you could always do this:

当然,你总是可以这样做:

swap(a,b);

But what if you want to rotate three values? You can do this with tuples:

但是如果你想旋转三个值怎么办?你可以用元组做到这一点:

tie(a,b,c) = make_tuple(b,c,a);

Tuples also make it much easier to return multiple variable from a function, which is probably a much more common case than swapping values. Using references to return values is certainly not very elegant.

元组还使从函数返回多个变量变得更加容易,这可能比交换值更常见。使用引用来返回值当然不是很优雅。

Are there any big drawbacks to tuples that I'm not thinking of? If not, why are they rarely used? Are they slower? Or is it just that people are not used to them? Is it a good idea to use tuples?

我没有想到元组有什么大的缺点吗?如果没有,为什么很少使用它们?他们慢吗?还是只是人们不习惯他们?使用元组是个好主意吗?

采纳答案by Alan De Smet

Because it's not yet standard. Anything non-standard has a much higher hurdle. Pieces of Boost have become popular because programmers were clamoring for them. (hash_map leaps to mind). But while tuple is handy, it's not such an overwhelming and clear win that people bother with it.

因为它还不是标准的。任何非标准的东西都有更高的障碍。Boost 的一部分变得流行,因为程序员们都在叫嚣着要它们。(hash_map 跃入脑海)。但是,虽然元组很方便,但它并不是一个压倒性和明显的胜利,人们会为此烦恼。

回答by Trey Hymanson

A cynical answer is that many people program in C++, but do not understand and/or use the higher level functionality. Sometimes it is because they are not allowed, but many simply do not try (or even understand).

一个愤世嫉俗的答案是,许多人用 C++ 编程,但不理解和/或使用更高级别的功能。有时是因为他们不被允许,但许多人根本不尝试(甚至不了解)。

As a non-boost example: how many folks use functionality found in <algorithm>?

作为一个非提升示例:有多少人使用<algorithm>?

In other words, many C++ programmers are simply C programmers using C++ compilers, and perhaps std::vectorand std::list. That is one reason why the use of boost::tupleis not more common.

换句话说,许多 C++ 程序员只是使用 C++ 编译器的 C 程序员,也许std::vectorstd::list. 这就是为什么使用boost::tuple不常见的原因之一。

回答by user21714

The C++ tuple syntax can be quite a bit more verbose than most people would like.

C++ 元组语法可能比大多数人希望的要冗长得多。

Consider:

考虑:

typedef boost::tuple<MyClass1,MyClass2,MyClass3> MyTuple;

So if you want to make extensive use of tuples you either get tuple typedefs everywhere or you get annoyingly long type names everywhere. I like tuples. I use them when necessary. But it's usually limited to a couple of situations, like an N-element index or when using multimaps to tie the range iterator pairs. And it's usually in a very limited scope.

所以如果你想大量使用元组,你要么到处都有元组类型定义,要么到处都有令人讨厌的长类型名称。我喜欢元组。我在必要时使用它们。但它通常仅限于几种情况,例如 N 元素索引或使用多重映射来绑定范围迭代器对时。而且它通常在一个非常有限的范围内。

It's all very ugly and hacky looking when compared to something like Haskell or Python. When C++0x gets here and we get the 'auto' keyword tuples will begin to look a lot more attractive.

与 Haskell 或 Python 之类的东西相比,这一切都非常丑陋和笨拙。当 C++0x 出现并且我们得到“auto”关键字时,元组将开始看起来更有吸引力。

The usefulness of tuples is inversely proportional to the number of keystrokes required to declare, pack, and unpack them.

元组的有用性与声明、打包和解包它们所需的击键次数成反比。

回答by ojrac

For me, it's habit, hands down: Tuples don't solve any new problems for me, just a few I can already handle just fine. Swapping values still feels easier the old fashioned way -- and, more importantly, I don't really think about how to swap "better." It's good enough as-is.

对我来说,这是习惯,毫无疑问:元组不会为我解决任何新问题,只有少数我已经可以处理得很好。用老式的方式交换值仍然感觉更容易——而且,更重要的是,我并没有真正考虑如何“更好地”交换。它已经足够好了。

Personally, I don't think tuples are a great solution to returning multiple values -- sounds like a job for structs.

就个人而言,我不认为元组是返回多个值的好方法——听起来像是structs的工作。

回答by Steve Jessop

But what if you want to rotate three values?

但是如果你想旋转三个值怎么办?

swap(a,b);
swap(b,c);  // I knew those permutation theory lectures would come in handy.

OK, so with 4 etc values, eventually the n-tuple becomes less code than n-1 swaps. And with default swap this does 6 assignments instead of the 4 you'd have if you implemented a three-cycle template yourself, although I'd hope the compiler would solve that for simple types.

好的,所以使用 4 个等值,最终 n 元组的代码比 n-1 交换少。使用默认交换,这会执行 6 次分配,而不是您自己实现三循环模板时的 4 次分配,尽管我希望编译器能够为简单类型解决这个问题。

You can come up with scenarios where swaps are unwieldy or inappropriate, for example:

您可以想出交换笨拙或不合适的场景,例如:

tie(a,b,c) = make_tuple(b*c,a*c,a*b);

is a bit awkward to unpack.

打开包装有点尴尬。

Point is, though, there are known ways of dealing with the most common situations that tuples are good for, and hence no great urgency to take up tuples. If nothing else, I'm not confident that:

不过,重点是,有一些已知的方法可以处理元组最适合的最常见情况,因此并没有急于处理元组。如果不出意外,我不相信:

tie(a,b,c) = make_tuple(b,c,a);

doesn't do 6 copies, making it utterly unsuitable for some types (collections being the most obvious). Feel free to persuade me that tuples are a good idea for "large" types, by saying this ain't so :-)

不做 6 个副本,使其完全不适合某些类型(集合是最明显的)。随意说服我元组是“大”类型的好主意,说不是这样:-)

For returning multiple values, tuples are perfect if the values are of incompatible types, but some folks don't like them if it's possible for the caller to get them in the wrong order. Some folks don't like multiple return values at all, and don't want to encourage their use by making them easier. Some folks just prefer named structures for in and out parameters, and probably couldn't be persuaded with a baseball bat to use tuples. No accounting for taste.

对于返回多个值,如果值的类型不兼容,元组是完美的,但是如果调用者可能以错误的顺序获取它们,那么有些人不喜欢它们。有些人根本不喜欢多个返回值,并且不想通过使它们更容易来鼓励它们的使用。有些人只是喜欢输入和输出参数的命名结构,并且可能无法用棒球棒说服使用元组。不考虑口味。

回答by igorlord

As many people pointed out, tuples are just not that useful as other features.

正如许多人指出的那样,元组不像其他功能那么有用。

  1. The swapping and rotating gimmicks are just gimmicks. They are utterly confusing to those who have not seen them before, and since it is pretty much everyone, these gimmicks are just poor software engineering practice.

  2. Returning multiple values using tuples is much less self-documenting then the alternatives -- returning named types or using named references. Without this self-documenting, it is easy to confuse the order of the returned values, if they are mutually convertible, and not be any wiser.

  1. 交换和旋转的噱头只是噱头。对于以前没有见过它们的人来说,它们完全令人困惑,而且由于几乎每个人都这样,这些噱头只是糟糕的软件工程实践。

  2. 使用元组返回多个值比替代方法要少得多的自我记录——返回命名类型或使用命名引用。如果没有这种自我记录,很容易混淆返回值的顺序,如果它们是相互转换的,并且不会更明智。

回答by Brian Neal

Not everyone can use boost, and TR1 isn't widely available yet.

不是每个人都可以使用 boost,而且 TR1 尚未广泛使用。

回答by Zack Yezek

You rarely see them because well-designed code usually doesn't need them- there are not to many cases in the wild where using an anonymous struct is superior to using a named one. Since all a tuple really represents is an anonymous struct, most coders in most situations just go with the real thing.

你很少看到它们,因为设计良好的代码通常不需要它们——在野外使用匿名结构优于使用命名结构的情况并不多。由于元组真正代表的是一个匿名结构,因此在大多数情况下,大多数编码人员只会使用真实的东西。

Say we have a function "f" where a tuple return might make sense. As a general rule, such functions are usually complicated enough that they can fail.

假设我们有一个函数“f”,其中元组返回可能有意义。作为一般规则,这些功能通常足够复杂,以至于它们可能会失败。

If "f" CAN fail, you need a status return- after all, you don't want callers to have to inspect every parameter to detect failure. "f" probably fits into the pattern:

如果 "f" CAN 失败,你需要一个状态返回——毕竟,你不希望调用者必须检查每个参数来检测失败。"f" 可能符合模式:

struct ReturnInts ( int y,z; }
bool f(int x, ReturnInts& vals);

int x = 0;
ReturnInts vals;
if(!f(x, vals)) {
    ..report error..
    ..error handling/return...
}

That isn't pretty, but look at how ugly the alternative is. Note that I still need a status value, but the code is no more readable and not shorter. It is probably slower too, since I incur the cost of 1 copy with the tuple.

这并不漂亮,但看看替代方案有多丑陋。请注意,我仍然需要一个状态值,但代码不再具有可读性,也不会更短。它也可能更慢,因为我承担了 1 个元组副本的成本。

std::tuple<int, int, bool> f(int x);
int x = 0;
std::tuple<int, int, bool> result = f(x); // or "auto result = f(x)"
if(!result.get<2>()) {
    ... report error, error handling ...
}

Another, significant downside is hidden in here- with "ReturnInts" I can add alter "f"'s return by modifying "ReturnInts" WITHOUT ALTERING "f"'s INTERFACE. The tuple solution does not offer that critical feature, which makes it the inferior answer for any library code.

另一个显着的缺点隐藏在这里 - 使用“ReturnInts”,我可以通过修改“ReturnInts”而不改变“f”的接口来添加改变“f”的返回值。元组解决方案不提供该关键功能,这使其成为任何库代码的次等答案。

回答by DanM

When using C++ on embedded systems, pulling in Boost libraries gets complex. They couple to each other, so library size grows. You return data structures or use parameter passing instead of tuples. When returning tuples in Python the data structure is in the order and type of the returned values its just not explicit.

在嵌入式系统上使用 C++ 时,引入 Boost 库会变得很复杂。它们彼此耦合,因此库的大小会增加。您返回数据结构或使用参数传递而不是元组。在 Python 中返回元组时,数据结构按返回值的顺序和类型排列,只是不明确。

回答by Zac

Certainly tuples can be useful, but as mentioned there's a bit of overhead and a hurdle or two you have to jump through before you can even really use them.

元组当然很有用,但如前所述,在真正使用它们之前,您必须跳过一些开销和一两个障碍。

If your program consistently finds places where you need to return multiple values or swap several values, it might be worth it to go the tuple route, but otherwise sometimes it's just easier to do things the classic way.

如果您的程序始终找到需要返回多个值或交换多个值的地方,那么走元组路线可能是值得的,但有时以经典方式做事会更容易。

Generally speaking, not everyone already has Boost installed, and I certainly wouldn't go through the hassle of downloading it and configuring my include directories to work with it just for its tuple facilities. I think you'll find that people already using Boost are more likely to find tuple uses in their programs than non-Boost users, and migrants from other languages (Python comes to mind) are more likely to simply be upset about the lack of tuples in C++ than to explore methods of adding tuple support.

一般来说,并不是每个人都已经安装了 Boost,我当然不会为了它的元组工具而下载它并配置我的包含目录来使用它。我想你会发现已经在使用 Boost 的人比非 Boost 用户更有可能在他们的程序中找到元组的用途,而来自其他语言的移民(想到 Python)更有可能只是因为缺少元组而感到不安在 C++ 中,而不是探索添加元组支持的方法。