2010-10-20 9 views
4

Je voudrais faire quelque chose comme ça (je suis conscient que ce ne sera pas compilé):C++ - utiliser dynamiquement référence ou variable locale

struct Container{ 
    vector<int> storage; 
}; 

float foo(Container* aContainer){ 
    if(aContainer!=NULL) 
     vector<int>& workingStorage=aContainer->storage; 
    else 
     vector<int> workingStorage; 


    workingStorage.reserve(1000000); 
    ....use workingStorage to calculate something...... 

    return calculated_result; 
} 

Donc - si je passe un conteneur à la fonction , je veux que la fonction utilise le vecteur dans le conteneur pour travailler avec au lieu d'une variable locale. Si aucun conteneur n'est fourni, il doit utiliser une variable locale.

bien sûr, je pourrais juste à la fin de la fonction copier la variable locale à la mémoire du conteneur, mais ce n'est pas ce que je veux faire.

Merci!

Répondre

14

Créez un std::vector<int> local nommé local_storage dans le cas où un conteneur n'est pas fourni par l'appelant, puis créez une référence au conteneur que vous allez utiliser.

std::vector<int> local_storage; 

std::vector<int>& working_storage = aContainer 
             ? aContainer->storage 
             : local_storage; 
+0

+1: Je vais vous suggérons d'utiliser un pointeur, car cela est un cas d'utilisation où les références ne coupent pas (ils ne sont pas des variables). Mais j'aime vraiment cette solution :-) –

+0

@James: Vous avez souligné à juste titre sur ma réponse (maintenant supprimée) que vous ne pouvez pas lier une référence à une variable temporaire. Mais l'expression ternaire de votre code n'évalue-t-elle pas également une variable temporaire? –

+0

@Oli: Non; c'est pourquoi je crée d'abord 'local_storage'; il est toujours créé, qu'il soit utilisé ou non. –

1
vector<int> temp; 
vector<int>& workingStorage = (aContainer!=NULL) ? aContainer->storage : temp; 
0

Pourquoi faites-vous pas sûr que aContainer->storage est initialisé avant de passer aContainer à foo. Cela rend votre code beaucoup plus propre. Avoir une instruction assert au début de la fonction pour vérifier aContainer->storage pour NULL.

+1

parce que je ne veux pas imposer d'avoir à fournir un conteneur. – Mat

3

Une façon d'aborder ce problème est de briser la fonction foo dans 2 fonctions

float foo(Container* aContainer){ 
    if(aContainer!=NULL) { 
    return foo_core(aContainer->storage); 
    } else { 
    vector<int> workingStorage; 
    return foo_core(workingStorage); 
} 

float foo_core(vector<int>& workingStorage) { 
    ... 
    // rest of original foo 
} 
+0

+1 n'est pas aussi chouette que James, mais il compense par sa clarté. –

1

La conception est apparemment horrible. Mais étant donné qu'un stockage externe optionnel est ce que vous voulez, JaredPar (sa réponse) a une bonne idée. Nettoyage que plus haut.

struct Container 
{ 
    vector<int> storage; 
}; 

double foo(vector<int>& workingStorage) 
{ 
    workingStorage.reserve(1000000); 
    //....use workingStorage to calculate something...... 
    return calculated_result; 
} 

double foo(Container& storageProvider) 
{ 
    return foo(storageProvider.storage); 
} 

double foo() 
{ 
    vector<int> storage; 
    return foo(storage); 
} 

Vive & HTH,

Questions connexes