2012-03-07 3 views
9

Eventuali duplicati:
Can I declare variables of different types in the initialization of a for loop?C++ Inizializzazione 2 iteratori differenti in un ciclo for

Mi piacerebbe avere un ciclo for in C++ che costruisce 2 diversi tipi di vettore iteratore in l'inizializzazione.

Ecco una vaga idea di quello che vorrei:

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

Chiunque sa che cosa è lo standard per fare in questa situazione? Non posso usare solo un vettore di doppio per intVec perché sto cercando una soluzione generale. [Cioè Potrei avere qualche funzione f che prende int a raddoppiare e quindi calcolare f (* i) * (* j)]

+5

Si prega di utilizzare '++ i, ++ j' invece di' && ', poiché ciò non funziona per gli iteratori. – Xeo

+2

L'incremento di un iteratore senza controllo è pericoloso. – Konrad

+0

modificato && in una virgola nel ciclo for. grazie – Derek

risposta

24

Si potrebbe dichiarare un std::pair con first e second come i tipi di iteratori:

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

Questa è una soluzione particolarmente intelligente, penso. Distrugge anche gli itratori alla fine, che faceva parte del mio obiettivo. Penso che quello che stavo inizialmente chiedendo era se fosse possibile inizializzare 2 diversi tipi in un ciclo for (che è impossibile). Ma questa soluzione è davvero bella e inaspettata. – Derek

+0

Come sottolineato da Alecs in un commento qui sotto, questa idea generalizza a structs come visto qui: http://stackoverflow.com/questions/8644707/can-i-declare-variables-of-different-types-in-the- inizializzazione del ciclo – Derek

+0

come fai a fare un passo avanti, come hai N? torna alla struttura, o c'è una cosa migliore da usare? – kdubs

3

Per esempio

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

è possibile dichiarare diversi var. solo dello stesso tipo nel for. E sei sicuro che con questa parte

++i && ++j 

? Credo che si desidera scrivere lì

++i, ++j 

Così, ovviamente, è necessario leggere informazioni di base su ciclo for in C++

+0

scusate, volevo dire ++ i, ++ j. tuttavia stavo cercando una soluzione che distruggesse anche gli iteratori alla fine del ciclo for, quindi non sono variabili globali. – Derek

+0

@Derek se sono di tipo diverso non c'è modo di farlo nel ciclo for. Nel tuo esempio non hai davvero bisogno di iteratori, puoi solo usare gli indici, ma suppongo che ci hai mostrato un codice molto semplificato – Alecs

+0

@Derek: Se è davvero necessario limitare il loro ambito, inserire le dichiarazioni e il ciclo nel proprio blocco. –

7

Non è possibile dichiarare le variabili di tipo diverso all'interno di un ciclo for.

Appena dichiararli fuori:

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

cosa succede con '++ i && ++ j'? Usa una virgola. – David

+0

@Dave è l'espressione di incremento che ha nella domanda, è quello che sto usando nella mia risposta. –

1

La cosa più facile da fare, a spese di allargare il campo di applicazione delle iteratori, sarebbe per loro issare solo fino al campo di applicazione che contiene:

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

Scopri il zip iterator. Fa esattamente quello che vuoi: parallelo itera su due o più sequenze contemporaneamente. Utilizzando questo, mi piacerebbe scrivere come:

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) 
{ 
    // ... 
} 

Certo, questo è ottenere un po 'più complicato se non si dispone di supporto per auto o un altro tipo di inferenza nel vostro caso specifico, ma può ancora essere molto carino 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

Non complicare eccessivamente le cose.

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

L'uso di iteratori non è una complicazione? – Konrad

+0

@Konrad: un indice è probabilmente più semplice di due iteratori. Ma l'OP ha chiesto una soluzione generale, e questo funziona solo per i contenitori ad accesso casuale. –

1

Sembra avete bisogno di 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; 
} 

ho usato il mio funtori, perché ho il sospetto che le moltiplica standard e più aspetto che entrambi gli operandi per essere di tipo simile, ma potrei sbagliarmi.