2

Inspired by this question I got thinking about what the perfect std::pair should look like. The compressed pair class (e.g. boost's) provides a pair that is whose size is reduced when one of its types is an empty class. The compressed pair requires getters (first(), second()), to hide the fact that the member with an empty type doesn't exist.

Secondly, according to the C++ docs: "Pairs are a particular case of tuple", yet they're implemented as a separate class. Why not use partial template specializations, such as

template <typename ...Args> class tuple {};
template <typename T1, typename T2> class tuple<T1, T2> {}; // Implements a compressed pair
template <typename T1, typename T2> using pair = tuple<T1, T2>;

Further, to provide a more unified API one could overload std::get and std::set for pair, and ditch the first() and second() accessors. Or one could have both :)

Questions

  1. Why is std::pair not a specialization of std::tuple?

  2. When might one use std::pair instead of a compressed pair? And even if there are cases, should the default be the compressed pair?

  3. Why isn't there a compressed tuple class?

Community
  • 1
  • 1
Judge
  • 372
  • 2
  • 8
  • 1
    The answer to 1 is probably because [`std::pair`](http://en.cppreference.com/w/cpp/utility/pair) was in the standard long before [`std::tuple`](http://en.cppreference.com/w/cpp/utility/tuple) was introduced in C++11. – Some programmer dude Jun 16 '16 at 08:18
  • @JoachimPileborg Good point, however I don't think it would break backwards compatibility to rewrite `std::pair` as a specialization of `std::tuple`, leaving `first` and `second` exposed. Although perhaps this would cause more confusion than it's worth. – Judge Jun 16 '16 at 08:30

1 Answers1

4
  1. pair predates tuple by good 10 years. It exist as a separate class mostly due to historical reasons and for backward compatibility. Making a breaking change to it is more trouble than it worth. If somebody wants tuple with two elements, they can just use tuple with two elements.

  2. I have trouble coming with non-artificial examples, the only real reason I think is using standard library classes, and backward compatibility with code assuming sizeof(pair<A,B>) >= sizeof(A) + sizeof(B) and similar.

  3. There is no compressed_tuple as std::tuple already performs EBO in every standard library implementation worth their salt.

Revolver_Ocelot
  • 8,609
  • 3
  • 30
  • 48
  • Thanks for the answer. I've had a quick play with `tuple` and `pair` and here are [my results](http://coliru.stacked-crooked.com/a/00420f1a17d3b205). Interestingly, `pair` is never compressed and `tuple` is compressed on g++ and clang++. So am I correct in concluding: always use `tuple` instead of `pair`, unless you need no-compression? And msvc isn't worth its salt? :) – Judge Jun 16 '16 at 09:23
  • @Judge which version of msvc are you using? I believe, latest one has EBO for tuple. I rarely have the need for compressing that badly, and most of the time I interact with STL, so usually I use pair unless I have empty class and thousands of instances or total pair size would exceed register size/have more than 50% overhead due to aligment issues. – Revolver_Ocelot Jun 16 '16 at 09:30
  • I'm using msvs 2015 Community edition (14.0.25123.00 update 2). Fair enough, but as a default surely compression can't hurt? Unless as you say, you're relying on the size of it. – Judge Jun 16 '16 at 09:42
  • @Judge Of course it cannot. I just use standard library + `auto`, so I have many pairs and lack of 2-element tuples. I do not care unless it is a bottleneck: I do not likely to reduce memory footprint or execution time noticeably otherwise. As for compiler: I cannot help with this. I do not use msvs, so I don't follow news about it. I might be a missing feature in compiler, or require specific flags, or something. I believe, standard library tuple is EBO enabled, though. – Revolver_Ocelot Jun 16 '16 at 09:52
  • Ah my bad, I hadn't realized `tuple` wasn't in the STL. Ok, thank you - I'll do some digging into msvc compiler features. – Judge Jun 16 '16 at 10:06
  • @Judge Nah, it is there, STL nowdays relates to everything templated from C++ Standard Library due to [Metonymy](https://en.wikipedia.org/wiki/Metonymy) – Revolver_Ocelot Jun 16 '16 at 10:09
  • Sorry, I believe I misunderstood "... and lack of 2-element tuples." to mean you don't have access to `std::tuple`, which I assumed was because you were using the original [STL](https://en.wikipedia.org/wiki/Standard_Template_Library) instead of the standard library, my bad. Am I correct in understanding that you have a lot of `std::pairs` in your code, but not many `std::tuples` and you're fine without compression, and thus happy with `std::pair`? – Judge Jun 16 '16 at 10:25
  • @Judge "lack of 2-element tuples" _in my code_. Standard library usually takes and returns pairs, so I just use native types. – Revolver_Ocelot Jun 16 '16 at 10:42
  • Anyone knows if there is any tuple compression with the gcc 6.2? – Anoroah Jun 02 '17 at 14:42