IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
logo

FAQ C++Consultez toutes les FAQ

Nombre d'auteurs : 34, nombre de questions : 368, derni�re mise � jour : 14 novembre 2021  Ajouter une question

 

Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur les forums de http://www.developpez.com et de l'exp�rience personnelle des auteurs.

Je tiens � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur ou si vous souhaitez devenir r�dacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.

SommaireBoost (12)
pr�c�dent sommaire suivant
 

Boost est un ensemble de biblioth�ques C++ gratuites et portables dont certaines seront int�gr�es au prochain standard C++ (voir Qu'est-ce que le Library Technical Report (tr1 / tr2) ?). On y retrouve donc naturellement les concepts de la biblioth�que standard actuelle, et en particulier ceux de la STL avec laquelle elle se m�lange parfaitement. Boost est tr�s riche : elle fournit notamment des biblioth�ques pour :


La liste compl�te des biblioth�ques class�es par cat�gories est disponible ici : http://www.boost.org/libs/.

La plupart de ces biblioth�ques tentent d'exploiter au maximum les possibilit�s du langage C++.
En fait, Boost se veut un laboratoire d'essais destin� � exp�rimenter de nouvelles biblioth�ques pour le C++. Il s'agit donc aussi d'une communaut� d'experts (dont plusieurs sont membres du comit� ISO de normalisation du C++) qui mettent un point d'honneur � ce qu'un maximum de compilateurs et de syst�mes soient support�s. Ils d�battent aussi de l'acceptation de nouvelles biblioth�ques et l'�volution de celles d�j� existantes, pr�figurant ainsi ce que � quoi ressemblera certainement la prochaine biblioth�que standard du C++ (voir Qu'est-ce que C++0x ?).

C'est donc l� que r�side le grand int�r�t de Boost. Outre son excellence technique et sa licence tr�s permissive (compatible avec la GPL) qui permet de l'utiliser gratuitement dans des projets commerciaux, Boost est aussi un choix tr�s viable sur le long terme. En effet, on peut l�gitimement esp�rer qu'un nombre important de ses biblioth�ques soient un jour standardis�es, ce qui en fait un outil dans lequel on peut investir du temps (et donc de l'argent) sans craindre de tout perdre au bout de quelques ann�es faute de support ou d'�volution.

Mis � jour le 4 juin 2018 Aurelien.Regat-Barrel

Une bonne partie des biblioth�ques qui composent Boost peuvent �tre utilis�es directement, sans n�cessiter aucune compilation. Si, dans un premier temps, votre utilisation de Boost se limite � ce genre de biblioth�que, installer Boost consiste simplement � rendre ses fichiers d'en-t�te accessibles � votre compilateur (INCLUDE PATH). R�f�rez vous � la documentation de ce dernier pour savoir comment proc�der. Quant aux autres biblioth�ques b�ties sur des appels syst�me telles que boost::filesystem, boost::date_time, elles n�cessitent auparavant d'�tre compil�es. Pour cela, Boost utilise son propre syst�me de g�n�ration de type make : Boost.Jam, ou plus simplement bjam. Il faut d'abord compiler ce dernier (ou r�cup�rer une version compil�e), avant de l'utiliser pour compiler la biblioth�que. Pour plus d'information sur la compilation de Boost, r�f�rez-vous � la documentation disponible en ligne ou encore dans le r�pertoire /tools/build/. Pensez aussi � effectuer une recherche sur nos forums.

Enfin, les utilisateurs de Visual C++ peuvent utiliser la version pr�te � l'emploi gracieusement mise � leur disposition par : Boost Consulting. Vous pouvez lire � ce sujet le tutorial Installer et utiliser Boost sous Windows avec Visual C++ 2005.

Mis � jour le 2 f�vrier 2007 Aurelien.Regat-Barrel

La principale source d'information sur Boost est la documentation officielle de chaque biblioth�que disponible sur le site de Boost. En dehors de cela, il existe malheureusement assez peu de r�f�rences sur le sujet.

Citons n�anmoins les tutoriels de Miles, en fran�ais : Un aper�u des possibilit�s des biblioth�ques de Boost.

Ainsi que quelques livres (en anglais) :


Et bien s�r la pr�sente FAQ qui comporte une section consacr�e � Boost.

Mis � jour le 3 f�vrier 2007 Aurelien.Regat-Barrel

Boost met � notre dispositions plusieurs types de pointeurs intelligents (voir Boost Smart Pointers). Les plus couramment utilis�s sont boost::shared_ptr et boost::shared_array (pour les tableaux) qui sont des pointeurs intelligents fonctionnant par comptage de r�f�rence :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream> 
#include <string> 
#include <boost/shared_ptr.hpp> 
  
class Test 
{ 
public: 
    Test( const char * Name ): 
        name( Name ) 
    { 
    } 
  
    ~Test() 
    { 
        std::cout << "Destruction de " << this->name << '\n';  
    } 
  
    void printName() 
    {  
        std::cout << this->name << '\n';  
    } 
  
private: 
    std::string name; 
}; 
  
// d�claration du type pointeur intelligent sur Test 
typedef boost::shared_ptr<Test> TestPtr; 
  
int main() 
{ 
    TestPtr ptr; // pointeur initialis� � NULL 
  
    { 
        // pointeur temporaire d�truit � la fin du bloc 
        TestPtr ptr_tmp( new Test( "objet1" ) ); 
  
        // initialiser ptr avec ptr_tmp 
        ptr = ptr_tmp; 
    } // ici, ptr_tmp est d�truit, mais ptr reste valide 
  
    ptr->printName(); // OK, affiche "objet1" 
  
    // r�initialiser le pointeur avec un nouvel objet 
    // objet1 est d�truit, objet2 est cr�� 
    ptr.reset( new Test( "objet2" ) ); 
  
    ptr->printName(); // OK, affiche "objet2" 
  
    // copie du pointeur sur objet2 
    TestPtr ptr2 = ptr; 
  
    // mise � NULL de ptr 
    ptr.reset(); // rien ne se passe 
  
    // mise � NULL de ptr2 
    ptr2.reset(); // objet2 est d�truit 
  
    // utilisation du pointeur NULL : erreur en mode Debug 
    ptr->printName(); // Assertion failed: px != 0 
}
Ce programme produit le r�sultat suivant s'il est compil� pour ne pas ignorer les assertions :
objet1
Destruction de objet1
objet2
Destruction de objet2
Assertion failed: px != 0

Si la donn�e manipul�e est une ressource un peu particuli�re, et ne doit pas �tre lib�r�e via delete, on peut sp�cifier via un foncteur le comportement � adopter lors de la lib�ration du pointeur intelligent :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
struct Delete 
{ 
    void operator ()(Test*& Ptr) const 
    { 
        cout << "Destruction"; 
        delete Ptr; 
    } 
}; 
  
int main() 
{ 
    shared_ptr<Test> Ptr(new Test(), Delete()); 
}
Voir Qu'est-ce qu'un foncteur ?

Mis � jour le 17 octobre 2005 Aurelien.Regat-Barrel Laurent Gomila

Elles sont tr�s nombreuses, et �quivalentes � celles sur les pointeurs bruts dans leur grande majorit�.

Prenons l'exemple de base suivant :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <boost/shared_ptr.hpp> 
  
class Base 
{ 
public: 
    virtual ~Base() {}; 
}; 
  
class Derived : public Base {}; 
  
typedef boost::shared_ptr<Base> BasePtr; 
typedef boost::shared_ptr<const Base> BaseConstPtr; 
typedef boost::shared_ptr<Derived> DerivedPtr; 
typedef boost::shared_ptr<const Derived> DerivedConstPtr;
L'upcasting est bien �videmment implicite, comme il le serait pour un pointeur brut :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void implicit_upcasting() 
{ 
// casting implicite sur des pointeurs bruts 
{     
    Derived *d = new Derived; 
    Base *b1 = d; 
    const Base *b2 = d; 
    delete d; 
} 
// �quivalent avec des pointeurs intelligents 
{     
    DerivedPtr d( new Derived ); 
    BasePtr b1 = d; 
    BaseConstPtr b2 = d; 
} 
}
Concernant le downcasting et le constcasting, il est n�cessaire de recourir � des fonctions libres sp�cialis�es :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void down_casting() 
{ 
// downcasting sur des pointeurs bruts 
{ 
    Base *b = new Derived; 
    Derived *d1 = static_cast<Derived*>( b ); 
    Derived *d2 = dynamic_cast<Derived*>( b ); 
    assert( d2 != 0 ); 
    delete b; 
} 
// �quivalent avec des pointeurs intelligents 
{ 
    BasePtr b( new Derived ); 
    DerivedPtr d1 = boost::static_pointer_cast<Derived>( b ); 
    DerivedPtr d2 = boost::dynamic_pointer_cast<Derived>( b ); 
    assert( d2 != 0 ); 
} 
} 
  
void const_casting() 
{     
// constcasting sur des pointeurs bruts 
{ 
    const Base *b_const = new Base; 
    Base *b2 = const_cast<Base*>( b_const ); 
    delete b_const; 
} 
// �quivalent avec des pointeurs intelligents 
{ 
    BaseConstPtr b_const( new Base ); 
    BasePtr b2 = boost::const_pointer_cast<Base>( b_const ); 
} 
}
Les trois fonctions de conversions pr�sent�es ci-dessus :
  • const_pointer_cast ;
  • static_pointer_cast ;
  • dynamic_pointer_cast.

ont �t� ratifi�es par le comit� de normalisation ISO et incluses dans le Technical Report 1 (tr1). Ce n'est pas le cas de quatre autres fonctions, qui ont �t� d�clar�es obsol�tes :
  • shared_static_cast ;
  • shared_dynamic_cast ;
  • shared_polymorphic_cast ;
  • shared_polymorphic_downcast.

Les deux premi�res sont respectivement �quivalentes � static_pointer_cast et dynamic_pointer_cast, et leur usage est donc fortement d�courag�. Les deux derni�res en revanche n'auront pas d'�quivalent dans le prochain standard. Elles correspondent en fait � boost::polymorphic_cast et boost::polymorphic_downcast appliqu�s aux shared_ptr (voir Comment utiliser les pointeurs intelligents de Boost ?).

L'exemple suivant illustre une possible utilisation de ces deux fonctions :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void deprecated_casting() 
{         
// downcasting sur des pointeurs bruts 
{ 
    Base *b = new Derived;     
    try 
    {         
        // downcasting levant std::bad_cast en cas d'�chec 
        Derived &d1 = dynamic_cast<Derived&>( *b );         
    } 
    catch ( const std::bad_cast & )  
    { 
    } 
    // downcasting provoquant une erreur uniquement en debug 
#ifdef _DEBUG 
    Derived *d2 = dynamic_cast<Derived*>( b ); 
    assert( d2 ); 
#else 
    Derived *d2 = static_cast<Derived*>( b ); 
#endif 
    delete b; 
} 
// �quivalent avec des pointeurs intelligents 
{ 
    BasePtr b( new Derived ); 
    try 
    {         
        // downcasting levant std::bad_cast en cas d'�chec 
        DerivedPtr d1 = boost::shared_polymorphic_cast<Derived>( b );         
    } 
    catch ( const std::bad_cast & ) 
    { 
    } 
    // downcasting provoquant une erreur uniquement en debug 
    DerivedPtr d2 = boost::shared_polymorphic_downcast<Derived>( b ); 
} 
}
La d�cision d'utiliser ou non ces deux fonctions vous incombe. Soyez simplement conscient que si vous le faites, vous rendrez votre code plus difficile � migrer le jour o� vous souhaiterez utiliser les shared_ptr standards.

Pour terminer, rappelons qu'il est possible de construire un shared_ptr � partir d'un std::auto_ptr (qui est alors invalid� par le shared_ptr construit), ce qui peut s'apparenter en quelque sorte � un cast d'auto_ptr en shared_ptr.

Code c++ : S�lectionner tout
1
2
3
std::auto_ptr<int> p1( new int ); 
boost::shared_ptr<int> p2( p1 ); 
// ici, p1 est invalide

Mis � jour le 3 f�vrier 2007 Aurelien.Regat-Barrel

boost::conversion introduit quatre types de cast sous forme de fonctions templates libres :

  • polymorphic_cast ;
  • polymorphic_downcast ;
  • lexical_cast ;
  • numeric_cast.

polymorphic_cast s'utilise comme dynamic_cast, mais contrairement � ce dernier qui poss�de un comportement diff�rent en fonction du type cast� (en cas d'erreur), polymorphic_cast l�ve syst�matiquement une exception std::bad_cast en cas d'�chec. Son comportement est donc le m�me que celui de dynamic_cast en cas de conversion de r�f�rences, et c'est pr�cis�ment pourquoi polymorphic_cast n'est pas pr�vu pour �tre utilis� avec ces derni�re.
Notez que polymorphic_cast peut �tre utilis� pour effectuer du cross-casting. Si vous utilisez dynamic_cast pour effectuer du downcasting (ou crosscasting) qui ne devrait jamais �chouer, pensez � utiliser polymorphic_cast qui vous �conomisera de tester le r�sultat du cast et permet aussi de mieux signaler dans le code l'intention d'effectuer un cast qui ne devrait pas �chouer.

Si l'utilisation de dynamic_cast vous procure des probl�me de performance dans votre programme, (ce qui devrait traduire un probl�me de conception, voir Pourquoi l'utilisation du downcasting est-il souvent une pratique � �viter ?) la solution habituelle est d'utiliser static_cast en remplacement.
Ce dernier est bien plus performant, mais aussi beaucoup plus risqu� dans la mesure o� le compilateur vous fait pleinement confiance, et est incapable de vous signaler une erreur (ce que dynamic_cast ou polymorphic_cast savent faire).

polymorphic_downcast est une sorte de compromis entre ces deux choix.
Compil� en version de d�veloppement (DEBUG), polymorphic_downcast se comporte un peu comme polymorphic_cast, sauf qu'en cas d'�chec une assertion failure est d�clench�e au lieu d'une exception. Dans le code de production (RELEASE), son appel est remplac� par un simple appel � static_cast, permettant ainsi d'obtenir un programme final performant sans trop p�naliser la fiabilit�.

polymorphic_downcast est malgr� tout � utiliser avec retenu, en tant qu'optimisation apr�s qu'un probl�me de performances ait �t� identifi�, et si ce dernier ne peut pas �tre r�solu en reconsid�rant le design de l'application.

� noter aussi, que contrairement � dynamic_cast et donc polymorphic_cast, polymorphic_downcast ne peut pas �tre utilis� pour du crosscasting.

Mis � jour le 3 f�vrier 2007 Aurelien.Regat-Barrel

Le programme suivant illustre comment utiliser boost::tokenizer pour d�couper une cha�ne de caract�res selon des s�parateurs par d�faut, ou selon une liste de s�parateurs bien pr�cis :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream> 
#include <boost/tokenizer.hpp> 
  
// d�coupe la chaine avec les s�parateurs par d�faut 
void split( const std::string & Msg ) 
{ 
    // utiliser le tokenizer par d�faut 
    boost::tokenizer<> tok( Msg ); 
  
    // it�rer la s�quence de tokens 
    for ( boost::tokenizer<>::const_iterator i = tok.begin(); 
          i != tok.end(); 
          ++i ) 
    { 
        // afficher chaque token extrait 
        std::cout << *i << '\n'; 
    } 
} 
  
// d�coupe la chaine selon les s�parateurs donn�s 
void split( const std::string & Msg, const std::string & Separators ) 
{ 
    // typedef pour all�ger l'�criture 
    typedef boost::tokenizer<boost::char_separator<char> > my_tok; 
  
    // s�parateur personnalis� 
    boost::char_separator<char> sep( Separators.c_str() ); 
  
    // construire le tokenizer personnalis� 
    my_tok tok( Msg, sep ); 
  
    // it�rer la s�quence de tokens 
    for ( my_tok::const_iterator i = tok.begin(); 
          i != tok.end(); 
          ++i ) 
    { 
        // afficher chaque token extrait 
        std::cout << *i << '\n'; 
    } 
} 
  
int main() 
{ 
    std::cout << "-- exemple 1 --\n"; 
  
    split( "mot1;mot2;   ;mot3;;mot4;mot5;" ); 
  
    std::cout << "-- exemple 2 --\n"; 
  
    split( "mot-compose1;mot,compose2;[mot][compose3];mot compose4;<mot><compose><5>", ";" ); 
}
Ce programme produit le r�sultat suivant :

Code : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
-- exemple 1 -- 
mot1 
mot2 
mot3 
mot4 
mot5 
-- exemple 2 -- 
mot-compose1 
mot,compose2 
[mot][compose3] 
mot compose4 
<mot><compose><5>
Notez que les token vides (";;" par exemple) ne sont pas pris en compte.

Mis � jour le 17 octobre 2005 Aurelien.Regat-Barrel

La question Comment supprimer correctement des �l�ments d'un conteneur ? illustre comment supprimer les pointeurs d'un conteneur au moyen de std::for_each et d'un foncteur fait sur mesure. Voici deux autres possibilit�s �quivalentes utilisant Boost, afin de vous faire une id�e de ses possibilit�s.

La premi�re combine std::for_each avec un foncteur de Boost : boost::checked_deleter, et la seconde utilise Boost.Foreach :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <list> 
#include <algorithm> 
#include <boost/checked_delete.hpp> 
  
int main()  
{  
    // Cr�ation d'une liste de pointeurs  
    std::list<int*> l;  
    l.push_back(new int(5));  
    l.push_back(new int(0));  
    l.push_back(new int(1));  
    l.push_back(new int(6));  
  
    // Destruction de la liste : attention il faut bien lib�rer les pointeurs avant la liste !  
    std::for_each(l.begin(), l.end(), boost::checked_deleter<int>());  
  
    return 0;  
}
Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <list> 
#include <algorithm> 
#include <boost/foreach.hpp> 
  
int main()  
{  
    // Cr�ation d'une liste de pointeurs  
    std::list<int*> l;  
    l.push_back(new int(5));  
    l.push_back(new int(0));  
    l.push_back(new int(1));  
    l.push_back(new int(6));  
  
    // Destruction de la liste : attention il faut bien lib�rer les pointeurs avant la liste ! 
    BOOST_FOREACH( int *pi, l ) 
    { 
       delete pi; 
    } 
  
    return 0;  
}

Mis � jour le 3 f�vrier 2007 Aurelien.Regat-Barrel

En programmation, dans certains langages, on a ce que l'on appelle les types somme. Il s'agit en fait de d�composer un type T en plusieurs sous-types T1, T2,� , TN. Une instance de T peut �tre obtenue par une valeur de type T1 ou T2 ou T3, mais pas deux types � la fois. Cela correspond vaguement aux unions pr�sentes en C et en C++. Par exemple, si vous r�alisez un interpr�teur d'expressions math�matiques du type '1+2-4', alors vous construirez g�n�ralement un arbre d'expressions, une expression �tant soit un nombre, soit une op�ration (+, -�) mettant en relation deux nombres, qui elle-m�me r�sultera en un nombre. Toutefois une expression ne peut pas �tre � la fois un nombre et une op�ration mettant en relation deux expressions.
Dans les deux cas, nous d�composons notre type 'expression' qui peut-�tre vu comme une union disjointe de deux types. C'est ce � quoi sert le type union en C et C++, toutefois il ne permet pas de g�rer des classes d�s qu'elles ont un constructeur par exemple.
En C++, un telle d�composition est rendue possible (bien que moins puissante et absolument pas int�gr�e au langage lui-m�me) gr�ce � Boost.Variant. En effet, nous pouvons d�finir un type C++ qui repr�sente �galement l'union disjointe de deux ensembles.

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
class A { };  
class B { };  
class C {}; 
class D {}; 
  
boost::variant<A,B,C,D,std::string,int> v; 
v = A(); // v contient une valeur de type A 
v = B(); // v contient une valeur de type B 
v = C(); // v contient une valeur de type C 
v = D(); // v contient une valeur de type D 
v = "Salut"; // v contient une valeur de type std::string 
v = 42; // v contient une valeur de type int
Un d�but de piste pour notre interpr�teur d'expressions arithm�tiques serait :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct Op 
{ 
  enum op_type { ADD, SUB }; 
  
  double e1, e2; 
  op_type op; 
}; 
  
double compute_op(const Op& o) 
{ 
  switch(o.op) 
  { 
    case Op::ADD: 
    return o.e1 + o.e2; break; 
    case Op::SUB: 
    return o.e1 - o.e2; break; 
  } 
} 
  
typedef boost::variant<double, Op> expression; 
  
double compute_expression(const expression& e) 
{ 
  if( double* d = boost::get<double>(&e) ) 
  { 
    return d; 
  } 
  Op* o = boost::get<Op>(&e); 
  return compute_op(*o); 
}

Mis � jour le 15 octobre 2009 Alp

La fonction template boost::get(), d�finie dans <boost/variant/get.hpp>, est un premier moyen de r�cup�rer la valeur d'un boost::variant. Il en existe 4 versions :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
template<typename U, typename T1, typename T2, ..., typename TN>  
  U * get(variant<T1, T2, ..., TN> * operand); // (1) 
template<typename U, typename T1, typename T2, ..., typename TN>  
  const U * get(const variant<T1, T2, ..., TN> * operand); // (2) 
template<typename U, typename T1, typename T2, ..., typename TN>  
  U & get(variant<T1, T2, ..., TN> & operand); // (3) 
template<typename U, typename T1, typename T2, ..., typename TN>  
  const U & get(const variant<T1, T2, ..., TN> & operand); // (4)
  • La premi�re version travaillera sur un pointeur vers boost::variant pour vous retourner un pointeur vers la valeur voulue.
  • La seconde version travaillera sur un pointeur vers un boost::variant constant pour vous retourner un pointeur vers la valeur constante voulue.
  • La troisi�me version travaillera sur une r�f�rence vers un boost::variant pour vous retourner une r�f�rence sur la valeur voulue.
  • La quatri�me version travaillera sur une r�f�rence sur un boost::variant constant pour vous retourner une r�f�rence sur la valeur constante voulue.

Dans le cas de (1) et (2), si le get �choue (si votre variant contient un int et que vous appelez get<string>(v) par exemple), alors la fonction vous retourne un pointeur nul.
Dans le cas de (3) et (4), si le get �choue, la fonction lance une exception bad_get (qui d�rive de std::exception et d�finit donc la fonction what() d�crivant ce qu'il s'est pass�).
De mani�re g�n�rale, la fonction get �chouera (retournera un pointeur nul pour (1) et (2), lancera une exception bad_get pour (3) et (4)) si la valeur courante contenue dans votre boost::variant n'est pas du type demand� explicitement avec get().
Pour terminer, un petit exemple d'utilisation :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream> 
#include <boost/variant.hpp> 
  
int main() 
{ 
  boost::variant<int, std::string> v; 
  v = 42; 
  
  int* i = boost::get<int>(&v); // l'entier point� par i vaut 42. 
  assert(*i == 42); 
  *i = 84; // cela a �galement modifi� la valeur contenue dans v 
  std::string* s = boost::get<std::string>(&v); 
  assert(s == NULL); // s vaut effectivement le pointeur nul 
  
  int& i2 = boost::get<int>(v); 
  assert(i2 == 84); 
  try 
    { 
      std::string& s = boost::get<std::string>(v); 
    } 
  catch (std::exception& e) 
    { 
      std::cout << "Exception ! " << e.what() << std::endl; 
    } 
  return 0; 
}
Ce code provoquera donc l'affichage suivant :
Exception ! boost::bad_get : failed value get using boost::get.

Mis � jour le 15 octobre 2009 Alp

Il y deux moyens pour simuler un typage faible en C++. On parle bien de simulation, le langage reste typ� statiquement.
Le premier d'entre eux est Boost variant :

Code c++ : S�lectionner tout
1
2
3
4
boost::variant< int, string > x; // d�clare une variable de type boost::variant en pr�cisant les types autoris�s. 
x = 42; //x contient un entier  
x = "hello, world"; // x contient une chaine de caract�res 
x = new Widget(); //erreur, x ne peut pas contenir un Widget.
Contrairement � une union, boost::variant peut inclure n'importe quel type, mais vous devez sp�cifier quels types sont autoris�s.
Vous pouvez m�me simuler un comportement polymorphe ad-hoc (surcharge de fonctions) avec boost::apply_visitor qui sera en plus v�rifi� � la compilation.
L'autre moyen est boost::any :

Code c++ : S�lectionner tout
1
2
3
4
boost::any x; 
x = 42; // x contient un entier 
x = "hello, world"; //x contient une chaine de caract�res  
x = new Widget(); // x contient un widget, pas d'erreur
Contrairement aux unions, boost::any accepte n'importe quel type. � l'inverse de boost::variant, boost::any ne vous laisse pas pr�ciser les types autoris�s, ce qui peut �tre une bonne ou mauvaise chose en fonction du degr� de laxisme souhait�. Aussi, vous n'avez aucun moyen de simuler une surcharge de fonctions et l'objet doit �tre allou� dynamiquement (sur le tas).
De fa�on int�ressante, ceci montre comme le C++ suit de fa�on ferme et efficace un sch�ma de typage statique quand c'est possible et dynamique quand c'est n�cessaire.

Quand avez vous besoin de quoi ?

Utilisez boost::variant quand vous voulez :
  • un objet capable de stocker les valeurs d'un nombre fini de types ;
  • une v�rification � la compilation du type visit� ;
  • une allocation efficace, qui se trouve sur la pile ;
  • et vous pouvez vivre avec d'horribles messages d'erreur quand le type attribu� n'est pas le bon.

Utilisez boost::any quand vous voulez :
  • la flexibilit� offerte par un objet capable de stocker virtuellement n'importe quel type ;
  • la flexibilit� offerte par any_cast ;
  • la garantie qu'il n'y aura pas d'exceptions lanc�es durant un swap.

Mis � jour le 15 octobre 2009 Davidbrcz

Oui, mais de mani�re confortable � partir de Visual C++ 7.1 seulement (Visual C++ .Net 2003).
Microsoft a consacr� un article � ce sujet qui fait aussi office de bonne introduction � cette biblioth�que : Boost for Visual C++ Developers.

L'article Installer et utiliser Boost/Boost.TR1 avec Visual C++ vous donnera les bases pour r�aliser cette installation

Mis � jour le 17 mars 2008 Aurelien.Regat-Barrel

Proposer une nouvelle r�ponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �a


R�ponse � la question

Liens sous la question
pr�c�dent sommaire suivant
 

Les sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.