From http://www.cplusplus.com/reference/utility/pair/, we know that std::pair
has two member variables, first
and second
.
Why did the STL designers decide to expose two member variables, first
and second
, instead of offering a getFirst()
and a getSecond()
?
std::pair is a class template that provides a way to store two heterogeneous objects as a single unit. A pair is a specific case of a std::tuple with two elements. If neither T1 nor T2 is a possibly cv-qualified class type with non-trivial destructor, or array thereof, the destructor of pair is trivial.
std::pair is a struct, the standard says the compiler determines the layout though the order must be maintained, so in the instance of std::pair<char,char> your compiler may decide to place 3-byte padding after each char for optimal alignment, so no you can't assume contiguous memory layout - end of story.
C++ pair is a type that is specified under the utility> header and is used to connect two pair values. The pair's values can be of separate or identical types. To view the values in a pair independently, the class has the member functions first() and second().
Today we are going to talk about C++ basic std::pair class in a way how and why it is broken. std::pair first appeared in C++98 as a pretty basic class with a very simple semantics — you have two types T1 and T2, you can write std::pair<T1, T2> and access .first and .second members with all intuitive copy, assignment, comparison operators, etc.
This is a minor and debatable thing but std::pair with trivial and non default zero initialized scalars is zero initialized: In contrast, std::array does not initialize their elements with the default construction (if the underlying type is trivial) and leaves this for the user.
std::pair first appeared in C++98 as a pretty basic class with a very simple semantics — you have two types T1 and T2, you can write std::pair<T1, T2> and access.first and.second members with all intuitive copy, assignment, comparison operators, etc.
Because static member variables are not part of the individual class objects (they are treated similarly to global variables, and get initialized when the program starts), you must explicitly define the static member outside of the class, in the global scope. In the example above, we do so via this line:
For the original C++03 std::pair
, functions to access the members would serve no useful purpose.
As of C++11 and later (we're now at C++17, with C++20 coming up fast) std::pair
is a special case of std::tuple
, where std::tuple
can have any number of items. As such it makes sense to have a parameterized getter, since it would be impractical to invent and standardize an arbitrary number of item names. Thus you can use std::get
also for a std::pair
.
So, the reasons for the design are historical, that the current std::pair
is the end result of an evolution towards more generality.
In other news:
regarding
” As far as I know, it will be better if encapsulating two member variables above and give a
getFirst();
andgetSecond()
no, that's rubbish.
That's like saying a hammer is always better, whether you're driving in nails, fastening with screws, or trimming a piece of wood. Especially in the last case a hammer is just not a useful tool. Hammers can be very useful, but that doesn't mean that they're “better” in general: that's just nonsense.
Getters and setters are usually useful if one thinks that getting or setting the value requires extra logic (changing some internal state). This can then be easily added into the method. In this case std::pair
is only used to provide 2 data values. Nothing more, nothing less. And thus, adding the verbosity of a getter and setter would be pointless.
The reason is that no real invariant needs to be imposed on the data structure, as std::pair
models a general-purpose container for two elements. In other words, an object of type std::pair<T, U>
is assumed to be valid for any possible first
and second
element of type T
and U
, respectively. Similarly, subsequent mutations in the value of its elements cannot really affect the validity of the std::pair
per se.
Alex Stepanov (the author of the STL) explicitly presents this general design principle during his course Efficient Programming with Components, when commenting on the singleton
container (i.e., a container of one element).
Thus, albeit the principle in itself can be a source of debate, this is the reason behind the shape of std::pair
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With