2008-11-08 14 views
6

¿Hay alguna forma de realizar una asignación paralela en C++? Actualmente, las compilaciones de abajo (con advertencias)Asignación paralela en 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; 
} 

y estampados:

a: 4 
b: 5 

Lo que me gustaría que imprimir ... si no fuera obvio, es:

a: 5 
b: 4 

Como en, digamos, ruby ​​o python.

Respuesta

16

Eso no es posible. El código de ejemplo

a, b = b, a; 

se interpreta de la siguiente manera:

a, (b = b), a 

No hace nada. El operador de coma hace que devuelva el valor de a (el operando más a la derecha). Debido a que la asignación se une más, b = b está en parens.

La forma correcta de hacer esto es sólo

std::swap(a, b); 

Boost incluye una clase tupla con el que se puede hacer

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

Es internamente crea una tupla de referencias a A y B, y luego asigna para ellos una tupla de b y a.

1

O Perl. Pero no, no es posible (por lo que yo sepa), es necesario utilizar una variable temporal, como en:

int a = 4; 
int b = 5; 

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

FYI, internamente dichas lenguas (o Perl al menos) crear una lista temporal { a, b }, luego asigne la lista a las dos variables. En otras palabras, esto es al menos tan eficiente, aunque solo sea un poco más desordenado.

3

La asignación en paralelo no se admite en C++. Los lenguajes que admiten esto generalmente tratan a,b,c como una lista en cualquier lado del operador de asignación, esta no es la forma en que funciona el operador de coma en C++. En C++, a, b evalúa a y luego b, por lo que a, b = b, a es lo mismo que a; b = b; a;.

0

O Lua ...
Hay trucos con C/C++, como usar xor u operaciones, pero con riesgo de desbordamiento y tal. Solo hazlo de la manera dolorosa, con tres asignaciones. No es un gran trato.

+0

podría querer mencionar que el truco xor también solo funciona en tipos integrales. Además, la promoción entera evitaría que se desborde, pero dos del mismo tipo no se desbordará con una operación xor 0b1110 xo 0b1010 siempre será 0b1100 en una operación en modo bit – Beached

0

No existe tal función en la Biblioteca estándar. Se podría escribir un conjunto de funciones de plantilla:

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

Eso es no trivial si hay aliasing, como en el ejemplo de intercambio.

+0

std :: swap (a, b) – Beached

0

Esta pregunta es muy antigua – Me tropecé con ella hoy ...
... y me preguntaba por qué nadie dio esta respuesta antes ...

creo, es posible hacerlo en C++ 11 similar como lo hace Python (bajo el capó):

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

He intentado esto en ideone.com. La salida fue:

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

Si no recuerdo mal (no soy un experto en Python), en Python, a, b denota un par. (Python Doc.: 5.3. Tuples and Sequences)

Este par se puede hacer en C++ 11 fácilmente, p. Ej. con std::pair. En este caso, hice un par de referencias y asigné el par de valores. Funciona como make_pair() carga ambas variables antes de asignar el par correcto (de valores) al par de referencias izquierdas.

Desplazándome de nuevo, me doy cuenta de que esta respuesta está cerca de la solución basada en impulso de Johannes answer.

Puede ser, la razón es que no funcionó en C++ 03. Intenté en coliru.stacked-crooked.com: Con -std=c++03, resulta terrible leer los errores del compilador – cambiando a -std=c++11 y compila y ejecuta correctamente como se describe arriba.

Negación

No puedo imaginar lo que esta solución es buena para la práctica ni lo que vale la pena que pueda tener. Esto no es lo que traté de hacer. Como muchas otras respuestas dicen "No funciona". En mi humilde opinión (deletreado correctamente de acuerdo con el lenguaje C++) ...