Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use std::pair, but rename .first and .second member names?

Tags:

A common design problem I run into, is that I bundle two variables together and then lose the ability to reference them in a meaningful way.

std::pair<int,int> cords;
cord.first = 0; //is .first the x or y coordinate?
cord.second = 0; //is .second the x or y coordinate?

I've considered writing basic structs instead, but then I lose a lot of the benefits that come along with std::pair:

  • make_pair
  • non-member overloaded operators
  • swap
  • get
  • etc.

Is there a way to rename or provide an alternative identifier for the first and second data members?

I was hoping to leverage all of the the functions that accept std::pair,
but still be able to use them in the following way:

std::pair<int,int> cords;  
//special magic to get an alternative name of access for each data member.

//.first and .second each have an alternative name.
cords.x = 1;
assert(cords.x == cords.first);
like image 539
Trevor Hickey Avatar asked Sep 15 '15 16:09

Trevor Hickey


People also ask

Is a tuple the same as a pair?

Tuples are immutable and ordered sequences of elements. In that regard, they're similar to immutable lists - however, commonly, tuples are used to represent pairs in Software Engineering.

Is std :: pair a tuple?

std::tuple is a generalization of std::pair. You can convert between tuples with two elements and pairs. The i-th element of a tuple t can be referenced by the function template std::get: std::get<i-1>(t).

What is std :: pair used for?

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.

Is std :: pair a container?

std::pair is not a Container. Its intention is to group two objects together. Instance of the std::pair is a class with two member objects.


1 Answers

One way you could get around this is to use std::tie. You can tie() the return into variables that you have named so that you have good names.

int x_pos, y_pos;

std::tie(x_pos, y_pos) = function_that_returns_pair_of_cords();

// now we can use x_pos and y_pos instead of pair_name.first and pair_name.second

Another benefit with this is if you ever change the function to return a tuple tie() will also work with that.


With C++17 we now have structured bindings which allow you to declare and bind multiple variables to the return of the function. This work with arrays, tuple/pair like objects and struct/classes (as long as they meet some requirments). Using structured bindings in this case lets use convert the above example into

auto [x_pos, y_pos] = function_that_returns_pair_of_cords();

You can also do

auto& [x_pos, y_pos] = cords;

and now x_pos is a reference to cords.first and y_pos is a reference to cords.second.

like image 186
NathanOliver Avatar answered Sep 21 '22 13:09

NathanOliver