2012-06-11 1 views
2

Ceci est le code actuel.Ici j'appelle for_each pour exécuter la fonction montrée dans sum.Can cela peut être réduit à l'écriture de la fonction à l'intérieur de l'instruction for_each elle-même?Est-il possible de réécrire cela comme un seul paquebot?

int S; 
struct sum 
{ 
sum(int& v): value(v){} 
void operator()(int data)const {value+=(int)((data+(data%S==0?0:S))/S)+2;} 
int& value; 
}; 
int main() 
{ 
    int cnt=0; 
    S=5; 
    for_each(flights.begin(),flights.end(),sum(cnt)); 
    cout<<cnt-2; 
    return 0; 
} 
+3

pourquoi voudriez-vous? – msw

+5

Vous pouvez le faire uniquement en C++ 11 avec les fonctions lambda. –

+4

Ceci est une question parfaitement valable à mon humble avis, bien que 'vols 'ne soit jamais déclaré, initialisé ou défini. – rubenvb

Répondre

9

En C++ 11, vous pouvez, en utilisant lambdas avec une capture:

int main() 
{ 
    int cnt = 0; 
    S = 5; 
    for_each(
    flights.begin(), flights.end(), 
    [&] (int data) { 
     cnt += (data + (data % S == 0 ? 0 : S))/S + 2; 
    }); 
    cout << cnt - 2; 
    return 0; 
} 

La façon dont cela se lit comme suit est la suivante: vous avez une fonction anonyme prenant un argument int, qui capture ([&]) le contexte environnant par référence. Notez que c'est aussi efficace que votre solution puisque le compilateur crée effectivement la structure du lambda pour vous.

- Comme Navaz l'a noté dans ses commentaires, la distribution est en réalité inutile. De plus, les lancers de style C sont généralement considérés comme obsolètes - utilisez plutôt les distributions C++.

+0

Maintenant, vous modifiez 'cnt': p – rubenvb

+0

En aparté: Combien de temps entre la mise à jour d'une langue et ne plus avoir à mettre des qualificatifs spéciaux dans les réponses que l'on fait, en effet, se référant à la langue dans sa version actuelle? ;-) – DevSolar

+0

@DevSolar Eh bien, dans le cas de C99, la qualification n'est importante qu'en parlant de MSVC, dans le cas de C++ 11, la même chose s'applique jusqu'à ce qu'ils implémentent correctement le langage. – rubenvb

4

Vous pouvez utiliser std::accumulate de <numeric> qui exprime parfaitement votre intention de construire une somme.

int main() 
{ 
    int flights[] = {1, 2, 3}; 
    int S = 5; 
    std::cout << std::accumulate(
     begin(flights), end(flights), 0, 
     [S] (int sum, int data) { return sum + (int)((data+(data%S==0?0:S))/S)+2; }) 
     - 2; 
} 

Bien que vous ayez demandé une seule doublure, je préfère donner à ce lambda non trivial un nom pour augmenter la lisibilité.

int main() 
{ 
    int flights[] = {1, 2, 3}; 
    auto theFooBarSum = [] (int sum, int data) 
     { return sum + (int)((data+(data%5==0?0:5))/5)+2; }; 
    int initialValue = 0; 

    std::cout << std::accumulate(
     begin(flights), end(flights), initialValue , theFooBarSum) - 2; 
} 
+0

Vous n'avez pas besoin de capturer tout par référence, vous devriez probablement capturer uniquement 'S' par valeur. –

+0

Cela fonctionne dans toutes les versions C++? – user1444426

+0

@Luc Touraille Correct, merci. – hansmaad

Questions connexes