2012-03-07 19 views
9

Duplicar posible:
Can I declare variables of different types in the initialization of a for loop?C++ Inicialización 2 iteradores diferentes en un bucle for

me gustaría tener un bucle en C++ que construye 2 tipos diferentes de iterador vector en la inicialización

Aquí está una idea aproximada de lo que me gustaría:

std::vector<double> dubVec; 
std::vector<int> intVec; 
double result = 0; 

dubVec.push_back(3.14); 
intVec.push_back(1); 

typedef std::vector<int>::iterator intIter; 
typedef std::vector<double>::iterator dubIter; 

for (intIter i = intVec.begin(), dubIter j = dubVec.begin(); i != intVec.end(); ++i, ++j) 
{ 
    result += (*i) * (*j); 
} 

Alguien sabe lo que es el estándar que hacer en esta situación? No puedo usar un vector de doble para intVec porque estoy buscando una solución general. [es decir. Podría tener alguna función f que toma int duplicar y luego calcular f (* i) * (* j)]

+5

Utilice '++ i, ++ j' en lugar de' && ', ya que eso no funciona para los iteradores. – Xeo

+2

Incrementar un iterador sin verificarlo es peligroso. – Konrad

+0

cambió && a una coma en el ciclo for. thx – Derek

Respuesta

24

Se puede declarar una std::pair con first y second como los tipos de iterador:

for (std::pair<intIter, dubIter> i(intVec.begin(), dubVec.begin()); 
    i.first != intVec.end() /* && i.second != dubVec.end() */; 
    ++i.first, ++i.second) 
{ 
    result += (*i.first) * (*i.second); 
} 
+0

Creo que esta es una solución particularmente inteligente. También destruye los operadores al final, lo cual era parte de mi objetivo. Creo que lo que inicialmente estaba preguntando era si era posible inicializar 2 tipos diferentes en un ciclo for (lo cual es imposible). Pero esta solución es realmente agradable e inesperada. – Derek

+0

Como lo señala Alecs en un comentario a continuación, esta idea se generaliza a las estructuras como se ve aquí: http://stackoverflow.com/questions/8644707/can-i-declare-variables-of-different-types-in-the- initialization-of-a-for loop – Derek

+0

¿Cómo se da un paso más adelante, cómo se tiene N? volver a la estructura, o hay algo mejor para usar? – kdubs

3

Por ejemplo

intIter i = intVec.begin(); 
dubIter j = dubVec.begin(); 
for (; i != intVec.end(); ++i && ++j) 
{ 
    result += (*i) * (*j); 
} 

puede declarar varias var. solo del mismo tipo en el para. Y está seguro con esta parte

++i && ++j 

? Creo que desea escribir no

++i, ++j 

Así que, obviamente, debe leer conceptos básicos acerca de bucle en C++

+0

lo siento, me referí a ++ i, ++ j. sin embargo, estaba buscando una solución que también destruyera los iteradores al final del ciclo for, por lo que no son variables globales. – Derek

+0

@Derek si son de tipos diferentes, no hay forma de hacerlo en el ciclo for. En su ejemplo, realmente no necesita iteradores, solo puede usar índices, pero supongo que nos mostró un fragmento de código muy simplificado. – Alecs

+0

@Derek: si realmente necesita restringir su alcance, coloque las declaraciones y el bucle en su propio bloque. –

7

No se puede declarar variables de diferentes tipos dentro de un bucle for.

Sólo declararlos fuera:

intIter i = intVec.begin(); 
dubIter j = dubVec.begin(); 
for (; i != intVec.end(); ++i && ++j) 
{ 
} 
+4

¿Qué pasa con '++ i && ++ j'? Usa una coma – David

+0

@Dave esa es la expresión de incremento que tiene en la pregunta, eso es lo que estoy usando en mi respuesta. –

1

La cosa más fácil de hacer, a costa de ampliar el alcance de los iteradores, sería simplemente izar ellos hasta el alcance que contiene:

intIter i; 
dubIter j; 
for (i = intVec.begin(), j = dubVec.begin(); i != intVec.end(); ++i && ++j) 
{ 
    result += (*i) * (*j); 
} 
1

Revisa el zip iterator. Hace exactamente lo que quiere: paralelo iterar sobre dos o más secuencias simultáneamente. Usando esto, me gustaría escribir como:

using namespace boost; 

for (auto i=make_zip_iterator(make_tuple(dubVec.begin(), intVec.begin())), 
      ie=make_zip_iterator(make_tuple(dubVec.end(), intVec.end())); 
      i!=ie; ++i) 
{ 
    // ... 
} 

Es cierto que esto es un poco más complicado si usted no tiene soporte para auto u otro tipo de inferencia en su caso específico llegar, pero todavía puede ser bastante agradable con un typedef.

0
intIter i; 
dubIter j; 
for (i = intVec.begin(), j = dubVec.begin(); i != intVec.end() && j != dubIter.end(); ++i, ++j) 
{ 
    result += (*i) * (*j); 
} 
1

No complicar demasiado las cosas.

for(size_t i = 0; i < intVec.size(); ++i) 
{ 
    result += intVec[i] * dubVec[i]; 
} 
+0

¿El uso de iteradores no es una complicación excesiva? – Konrad

+0

@Konrad: Un índice es posiblemente más simple que dos iteradores. Pero el OP sí solicitó una solución general, y esto solo funciona para contenedores de acceso aleatorio. –

1

Parece que necesita un inner_product algorithm.

#include <vector> 
#include <functional> 
#include <numeric> 
#include <iostream> 

struct my_plus 
{ 
    double operator()(int i, double d) 
    { 
     return d + i; 
    } 
}; 

struct my_multiplies 
{ 
    double operator()(int i, double d) 
    { 
     return d * i; 
    } 
}; 

int main() 
{ 
    std::vector<double> dubVec; 
    std::vector<int> intVec; 
    double result = 0; 

    dubVec.push_back(3.14); 
    intVec.push_back(1); 

    result = std::inner_product(intVec.begin(), 
           intVec.end(), 
           dubVec.begin(), 
           0.0, 
           my_plus(), 
           my_multiplies()); 
    std::cout << result << std::endl; 
} 

usaba mis propias palabras funcionales, porque sospecho que se multiplica el estándar y además espero ambos operandos sean de tipo similar, pero puedo estar equivocado.

Cuestiones relacionadas