2010-11-08 9 views
10

Je n'ai pas réussi à comprendre cela. C'est facile de créer deux cteurs, mais je voulais savoir s'il y avait un moyen facile de le faire.Comment passer std :: map comme paramètre de constructeur par défaut

Comment peut-on passer un std::map comme paramètre par défaut à un ctor, par ex.

Foo::Foo(int arg1, int arg2, const std::map<std::string, std::string> = VAL) 

J'ai essayé 0, null et NULL comme VAL, aucun des travaux parce qu'ils sont tous de type int, g ++ se plaint. Quelle est la valeur par défaut correcte à utiliser ici?

Ou est ce genre de chose n'est pas une bonne idée?

Répondre

22

L'expression correcte pour VAL est std::map<std::string, std::string>(). Je pense que l'air long et laid, donc je serais probablement ajouter un membre de typedef publique à la classe:

class Foo { 
public: 
    typedef std::map<std::string, std::string> map_type; 
    Foo(int arg1, int arg2, const map_type = map_type()); 
    // ... 
}; 

Et en passant, avez-vous dire pour le dernier argument du constructeur d'être une référence? const map_type& est probablement mieux que juste const map_type.

+5

+1 pour être la seule solution qui a mis la valeur par défaut dans la déclaration * * et non dans le *définition*. –

5

Vous créez une valeur temporaire initialisée. Par exemple:

Foo::Foo(int arg1, 
     int arg2, 
     const std::map<std::string, std::string>& the_map = 
      std::map<std::string, std::string>()) 
{ 
} 

(A typedef pourrait aider à rendre plus lisible dans votre code)

2

En premier lieu, et tangentailly, vous passez la carte par valeur const, ce qui est inutile et probablement pas ce que tu veux vraiment. Vous voulez probablement passer par const référence, de sorte que vous ne faites pas une copie de la carte, et vous vous assurez que votre fonction ne modifie pas la carte.

Maintenant, si vous voulez que votre paramètre par défaut à une carte vide, vous le faites en le construisant, comme ceci:

Foo::Foo(int arg1, int arg2, const std::map<std::string, std::string>& = std::map<std::string, std::string>()) 
0

Depuis C++ 11 vous pouvez utiliser aggregate initialization:

void foo(std::map<std::string, std::string> myMap = {}); 

Exemple:

#include <iostream> 
#include <map> 
#include <string> 

void foo(std::map<std::string, std::string> myMap = {}) 
{ 
    for(auto it = std::begin(myMap); it != std::end(myMap); ++it) 
     std::cout << it->first << " : " << it->second << '\n'; 
} 

int main(int, char*[]) 
{ 
    const std::map<std::string, std::string> animalKids = { 
     { "antelope", "calf" }, { "ant", "antling" }, 
     { "baboon", "infant" }, { "bear", "cub" }, 
     { "bee", "larva" }, { "cat", "kitten" } 
    }; 

    foo(); 
    foo(animalKids); 

    return 0; 
} 
Questions connexes