There is a very popular question about "std::pair vs struct with two fields". But I have a question about reassigning first
and second
values to semantically named variables. In regular scenario we have something like this:
const std::pair<const int, const int> result = processSomething();
std::cout << result.second << " of " << result.first << std::endl;
But what if we assign them to reference variables first:
const std::pair<const int, const int> result = processSomething();
const int &numTotal = result.first;
const int &numSuccessful = result.second;
std::cout << numSuccessful << " of " << numTotal << std::endl;
This freeing us from writing comments about semantics of first
and second
. What disadvantages of this way? Do compilers will reserve stack for numTotal
and numSuccessful
? Will perfomance drop if this pattern used in main loop of application?
Changed from regular variables to reference variables (thank you for comments)
I don't see any serious disadvantages, variables with meaningful names can help make the code much clearer. A decent optimizing compiler should be able to remove any overhead from the extra references in simple cases such as your example, but maybe not for more complex cases where the types are not identical (e.g. they have different const-qualification or require conversions).
There is another option that might be clearer in some cases: Instead of initializing a pair
with the result, you could create the variables you want, then create a pair
of references to those variables, and assign to them via the references:
int numTotal;
int NumSuccessful;
std::pair<int&, int&> result(numTotal, numSuccessful);
result = processSomething();
Or the same thing, without a named variable for the pair of references:
int numTotal;
int NumSuccessful;
std::pair<int&, int&>(numTotal, numSuccessful) = processSomething();
or in C++11 you can use the standard tie
function:
int numTotal;
int NumSuccessful;
std::tie(numTotal, numSuccessful) = processSomething();
A more unusual solution involves no temporary objects and allows you to make the variables const
, by using a local type with meaningful member names:
struct Num {
Num(std::pair<const int, const int> p) : total(p.first), successful(p.second) { }
int total;
int sucessful;
};
const Num num = processSomething();
std::cout << num.successful << '/' << num.total << '\n';