Parallel assignment in C++

前端 未结 6 855
醉酒成梦
醉酒成梦 2021-01-18 13:53

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

#include  

int main() { 
  int a = 4;
           


        
相关标签:
6条回答
  • 2021-01-18 13:58

    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;.

    0 讨论(0)
  • 2021-01-18 14:02

    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.

    0 讨论(0)
  • 2021-01-18 14:04

    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.

    0 讨论(0)
  • 2021-01-18 14:08

    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.

    0 讨论(0)
  • 2021-01-18 14:10

    This question is very old – I just stumbled into it today...
    ...and wondered why nobody gave this answer before...

    I think, it's possible to do it in C++11 similar like Python does it (under the hood):

    #include <iostream>
    using namespace std;
    
    int main()
    {
      int a = 4, b = 5;
      cout << "Before assignment: a: " << a << ", b: " << b << endl;
      pair<int&, int&> ba(b, a);
      ba = make_pair(a, b); // <===: (b, a) = (a, b)
      cout << "After assignment : a: " << a << ", b: " << b << endl;
      return 0;
    }
    

    I tried this out on ideone.com. The output was:

    Before assignment: a: 4, b: 5
    After assignment : a: 5, b: 4
    

    If I remember right (I'm not a Python expert), in Python, a, b denotes a pair. (Python Doc.: 5.3. Tuples and Sequences)

    Such pair can be done in C++ 11 easily e.g. with std::pair. In this case, I made a pair of references and assigned the pair of values. It works as the make_pair() loads both variables before the right pair (of values) is assigned to the left pair of references.

    Scrolling again, I realize that this answer is close to the boost based solution of Johannes answer.

    May be, the reason is that it didn't work in C++03. I tried in coliru.stacked-crooked.com: With -std=c++03 it yields terrible to read compiler errors – changing to -std=c++11 and it compiles and executes fine as described above.

    Disclaimer

    I just cannot imagine what this solution is good for nor what practical worth it may have. This is not what I tried to do. As many other answers states "It does not work." IMHO it does (spelling it right according to the C++ language)...

    0 讨论(0)
  • 2021-01-18 14:21

    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.

    0 讨论(0)
提交回复
热议问题