2017-04-27 2 views
-1

J'essaie d'utiliser l'opérateur "..." mais se ennuis:Obtenir des déchets lors de l'utilisation opérateur ...

void Func(int diff, CTester* pcTester, int params ...) 
{ 
    va_list ap; 
    va_start(ap, params); 
    for(int i = 0; i < params; i++) { 
     int val = va_arg(ap, int); 
     cout << "[" << i << "] = " << val << "\n"; 
     if (diff > val) { 
      // some logic 
     } 
    } 
    va_end(ap); 
} 

J'appelle Func ainsi:

Func(1359, pcTester, 10, 20, 30, 40); 

Je me attends à voir dans la console les impressions de [0] = 10 [1] = 20 [2] = 30 [3] = 40 Mais je reçois trop de copies:

[0] = 20 
[1] = 30 
[2] = 40 
[3] = 4197568 
[4] = 26221600 
[5] = 0 
[6] = 4196640 
[7] = 4197568 
[8] = 1152895024 
[9] = 0 

Comme vous pouvez le voir j'ai e 10 imprime (au lieu de 4) et la première valeur (10) ne figure pas dans la liste

Qu'est-ce que je fais de mal?

+1

Vous ne 'pour int i = 0; je

+0

Le '...' dans votre code n'est pas un opérateur (un opérateur opère sur d'autres expressions pour produire une autre expression, par exemple ' + 'peut fonctionner sur' 2' et '3' pour donner' 5'). Le '...' fait en fait partie de la syntaxe pour une liste de paramètres de fonction qui indique qu'il y aura des arguments non-prototypés à suivre –

Répondre

2

Votre programme a un comportement indéfini.

Vous traitez l'argument params comme étant le nombre d'arguments qui le suivent mais vous ne passez pas assez d'arguments.

Func(1359, pcTester, 10, 20, 30, 40); // There are only 3 arguments after 10. 

Vous devez vous assurer qu'ils correspondent. Utilisation:

// 3 arguments after params 
Func(1359, pcTester, 3, 20, 30, 40); 

ou

// 4 arguments after params 
Func(1359, pcTester, 4, 10, 20, 30, 40); 

ou

// 10 arguments after params 
Func(1359, pcTester, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110); 
+1

vous n'avez pas répondu à sa question. dans votre exemple, il veut voir la première valeur (10) –

+0

@Boom, c'est corrigé maintenant. –

1

Une meilleure utilisation C++ modèles variadique et un std::initializer_list pour fixer le type de int.

#include <iostream> 
#include <initializer_list> 

class CTester {}; 

template < typename ... Args > 
void Func(int diff, CTester* pcTester, Args ... params) 
{ 
    int i = 0; 
    for(int val : std::initializer_list<int>{ params ... }) 
    { 
    std::cout << "[" << i << "] = " << val << "\n"; 
    if (diff > val) { 
     // some logic 
    } 
    ++i; 
    } 
} 

int main() 
{ 
    CTester * pcTester = new CTester; 
    Func(1359, pcTester, 10, 20, 30, 40); 
    delete pcTester; 
} 

Demo on ideone