Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloads of std::minmax() and std::tie

Tags:

c++

c++11

The std::minmax function introduced in C++11 is supposed to return a pair of respectively the lowest and the greatest of the given values.

In this example:

int a = 6, b = 5;
auto p = std::minmax(a, b);
std::cout << "p.first = " << p.first << std::endl;
std::cout << "p.second = " << p.second << std::endl;

This works as advertised and prints

p.first = 5
p.second = 6

Now I would like to effectively modify a and b to force b to be lower than a, as if running this code:

if (b > a)
    std::swap(a, b);

So I have written this:

int a = 5, b = 6;
std::tie(b, a) = std::minmax(a, b);
std::cout << "a = " << a << std::endl;
std::cout << "b = " << b << std::endl;

However, this prints:

a = 5
b = 5

Using the initializer_list overload instead, like this:

std::tie(b, a) = std::minmax({a, b});

causes the expected result to be printed:

a = 6
b = 5

The compiler is GCC 4.7.1 (also tested with GCC 4.8.1 on Linux and Windows with Mingw-w64). I have created an SSCCE at http://ideone.com/fA0qw5.

Why is the two-arguments overload not doing what it is supposed to do when using std::tie ?

like image 307
SirDarius Avatar asked Sep 20 '13 08:09

SirDarius


1 Answers

The problem is that std::minmax returns references for the 2-argument version. That way, as soon as b in the std::tie(b, a) is assigned, the change is reflected in the b part of the returned std::pair, giving it the value of 5 - which in turn is assigned to the a in std::tie(b, a), yielding (5, 5) as the result.

like image 195
Xeo Avatar answered Nov 09 '22 02:11

Xeo