tags:

views:

388

answers:

5

Is there any way of doing parallel assignment in C++? Currently, the below compiles (with warnings)

#include <iostream> 

int main() { 
  int a = 4;
  int b = 5;
  a, b = b, a;
  std::cout << "a: " << a << endl
            << "b: " << b << endl;

  return 0;
}

and prints:

a: 4
b: 5

What I'd like it to print ... if it weren't obvious, is:

a: 5
b: 4

As in, say, ruby, or python.

+1  A: 

Or Perl. But no, it's not possible (as far as I'm aware), you need to use a temporary variable, as in:

int a = 4;
int b = 5;

{
    int tmp = a;
    a = b;
    b = tmp;
}

FYI, internally those languages (or Perl atleast) create a temporary list { a, b }, then assign the list to the two variables. In other words, this is atleast as performant, if only a little more messy.

Matthew Scharley
+12  A: 

That's not possible. Your code example

a, b = b, a;

is interpreted in the following way:

a, (b = b), a

It does nothing. The comma operator makes it return the value of a (the right most operand). Because assignment binds tighter, b = b is in parens.

The proper way doing this is just

std::swap(a, b);

Boost includes a tuple class with which you can do

tie(a, b) = make_tuple(b, a);

It internally creates a tuple of references to a and b, and then assigned to them a tuple of b and a.

Johannes Schaub - litb
+3  A: 

Parallel assignment is not supported in C++. Languages that support this usually treat a,b,c as a list on either side of the assignment operator, this isn't the way the comma operator works in C++. In C++, a, b evaluates a and then b, so a, b = b, a is the same as a; b = b; a;.

Robert Gamble
A: 

Or Lua...
There are tricks with C/C++, like using xor or operations, but with risk of overflow and such. Just do it the painful way, with three assignments. Not a big deal.

PhiLho
A: 

There is no such function in the Standard Library. You could write a set of template functions :

template <typename T1> void ParAssign(T1& Lhs_1, T1 const& Rhs1);
template <typename T1, typename T2> void ParAssign(T1& Lhs1, T2& Lhs2, T1 const& Rhs1, T2 const& Rhs2);
// etc.
ParAssign(a,b,
          b,a);

That's non-trivial if there is aliasing, as in your swap example.

MSalters