2010-01-03 4 views
4

Chaque fois que la conversion numeric_cast<> de boost échoue, il lève une exception. Y a-t-il un modèle similaire dans boost qui me permet de spécifier une valeur par défaut, ou est-ce que attraper l'exception est la seule chose que je peux faire dans ce cas?Boost numeric_cast <> avec une valeur par défaut au lieu d'une exception?

Je ne m'inquiète pas trop des performances de toute la gestion des exceptions supplémentaires, mais je préfère utiliser un modèle standard plutôt que d'écrire des fonctions wrapper inutiles. D'ailleurs, d'après l'expérience passée, je pensais qu'il est probable que boost ait réellement ce à quoi je pense, et je ne l'ai tout simplement pas trouvé.

+0

Le fait est qu'il * lance * une exception. Si vous n'en voulez pas, lancez simplement. –

+0

nobugs: numeric \ _cast détecte les débordements et les débordements, alors que "casting" ne le sera pas. –

Répondre

6

La fonction numeric_cast appelle simplement la classe de modèle boost::numeric::converter avec les arguments par défaut. L'un des arguments est OverflowHandler et la valeur par défaut est def_overflow_handler, mais vous pouvez spécifier silent_overflow_handler pour supprimer l'exception à la place.

Ensuite, spécifiez l'argument FloatToIntRounder qui fournira votre valeur par défaut si l'argument d'entrée est en dehors de votre plage souhaitée. L'argument est normalement utilisé pour fournir un entier pour arrondir à partir d'un type à virgule flottante, mais vous pouvez vraiment l'utiliser pour tout ce que vous voulez. Plus d'informations, plus le code décrivant la séquence des événements, au converter documentation. Pour autant que je sache, Boost n'a pas ce que vous pensez, mais il vous donne la possibilité de le construire vous-même.

3

Cela a été discuté plusieurs fois sur la liste de diffusion boost, cependant, aucune solution unifiée n'a encore été acceptée. Vous pouvez utiliser la fonction d'espace réservé suivant jusque-là, cependant, en raison d'une exception soulevant ce n'est ni style, ni beau-sage efficacité:

template<typename Target, typename Source> 
    inline Target default_numeric_cast(Source arg, Target def) 
{ 
    try { 
     return numeric_cast<Target,Source>(arg); 
    } catch (...) { 
     return def; 
    } 
} 

Cependant, une solution serait waaay plus efficace sur mesure.

5
template<class Target, class Source> 
typename boost::numeric::converter<Target,Source>::result_type 
numeric_cast_defaulted(Source arg, Target default_value = Target()) try { 
    return boost::numeric_cast<Target>(Source); 
} 
catch (boost::bad_numeric_cast&) { 
    return default_value; 
} 
Questions connexes