【问题标题】:Parallel assignment in C++C++ 中的并行赋值
【发布时间】:2010-09-21 11:12:41
【问题描述】:

有没有办法在 C++ 中进行并行赋值?目前,以下编译(带有警告)

#include <iostream> 

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

  return 0;
}

并打印:

a: 4
b: 5

我希望它打印出来......如果它不明显,是:

a: 5
b: 4

例如,ruby 或 python。

【问题讨论】:

    标签: c++


    【解决方案1】:

    或 Perl。但是不,这是不可能的(据我所知),您需要使用临时变量,如:

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

    仅供参考,这些语言(或至少 Perl)在内部创建一个临时列表 { a, b },然后将该列表分配给这两个变量。换句话说,这至少是高性能的,即使只是有点混乱。

    【讨论】:

      【解决方案2】:

      这是不可能的。您的代码示例

      a, b = b, a;
      

      解释如下:

      a, (b = b), a
      

      它什么都不做。逗号运算符使其返回 a(最右边的操作数)的值。因为赋值绑定更紧密,所以 b = b 在括号中。

      这样做的正确方法只是

      std::swap(a, b);
      

      Boost 包含一个元组类,你可以用它来做

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

      它在内部创建一个对 a 和 b 的引用的元组,然后为它们分配一个 b 和 a 的元组。

      【讨论】:

        【解决方案3】:

        C++ 不支持并行赋值。支持这一点的语言通常将a,b,c 视为赋值运算符两侧的列表,这不是逗号运算符在 C++ 中的工作方式。在 C++ 中,a, b 先计算 a,然后计算 b,因此 a, b = b, aa; b = b; a; 相同。

        【讨论】:

          【解决方案4】:

          或者 Lua...
          C/C++ 有一些技巧,例如使用 xor 或操作,但存在溢出等风险。只需以痛苦的方式完成三个任务即可。没什么大不了的。

          【讨论】:

          • 可能想提一下 xor 技巧也只适用于整数类型。此外,整数提升将防止它溢出,但相同类型的两个不会通过 xor 操作溢出 0b1110 xor 0b1010 在它是按位操作时将始终为 0b1100
          【解决方案5】:

          标准库中没有这样的函数。您可以编写一组模板函数:

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

          如果存在别名,那就不是微不足道的了,就像在你的交换示例中一样。

          【讨论】:

          • std::swap(a, b)
          【解决方案6】:

          这个问题很老了——我今天才偶然发现...
          ...并想知道为什么以前没有人给出这个答案...

          我认为,在 C++11 中可以像 Python 一样(在底层)这样做:

          #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;
          }
          

          我在ideone.com 上试过这个。输出是:

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

          如果我没记错的话(我不是 Python 专家),在 Python 中,a, b 表示一对。 (Python Doc.: 5.3. Tuples and Sequences)

          这样的配对可以在 C++ 11 中轻松完成,例如与std::pair。在这种情况下,我做了一对引用并分配了这对值。它的工作原理是 make_pair() 在将右侧(值)对分配给左侧引用对之前加载两个变量。

          再次滚动,我意识到这个答案接近Johannes answer 的基于提升的解决方案。

          可能是,原因是它在 C++03 中不起作用。我在 coliru.stacked-crooked.com 中尝试过:使用 -std=c++03 会产生可怕的编译器错误读取 - 更改为 -std=c++11 并且它编译和执行都很好,如上所述。

          免责声明

          我无法想象这个解决方案有什么好处,也无法想象它有什么实际价值。这不是我试图做的。正如许多其他答案所说“它不起作用”。恕我直言(根据 C++ 语言拼写正确)...

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-04-18
            • 2011-01-12
            • 1970-01-01
            • 2021-08-13
            • 1970-01-01
            • 1970-01-01
            • 2013-09-19
            相关资源
            最近更新 更多