Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 20/08/2011, à 19:24

helly

[résolu]C++, type numérique

Plop les gens.
Je cherche une fonction/machin pour intégrer dans un template.
Je cherche un moyen de savoir si un type inconnu donné en argument est un type numérique ou non.
On parle là bien de types (int, float,short…) pas de variables !
Je pensais trouver ça dans std::numeric_limits, notament le membre !!is_specialized, mais cette valeur est à true même pour des types non numériques, les std::string par exemple.
Brf, je sèche hmm.

Dernière modification par helly (Le 20/08/2011, à 21:46)


Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.

Hors ligne

#2 Le 20/08/2011, à 20:46

ehmicky

Re : [résolu]C++, type numérique

Salut,
Pour moi, cela marche avec is_specialized (false si type builtin (entiers (dont char et pointeurs) et floats), true si type complexe (classe, enum, struct, union, etc.) :

#include    <iostream>
#include    <limits>

namespace test
{
    template <class T>
    void MaFonction(const T Argument)
    {
        std::cout    << "L'argument " << Argument;
        if ( ! std::numeric_limits<T>::is_specialized )
            std::cout    << " n'est pas ";
        else
            std::cout    << " est ";
        std::cout    << "un type numérique" << std::endl;
    }
}

int main()
{
    test::MaFonction(0);
    test::MaFonction(1.2);
    test::MaFonction(std::string("Zero"));
    return 0;
}

Donne :

L'argument 0 est un type numérique
L'argument 1.2 est un type numérique
L'argument Zero n'est pas un type numérique

Sinon, tu as aussi boost::concept_check qui permet de faire ça avec des macros. Je trouve cela plus pratique, parce que tu peux personnaliser selon tes besoins, et les messages d'erreur sont plus clairs. Par ailleurs, si par exemple, tu penses vouloir savoir si deux arguments d'une fonction sont de type numérique parce qu'à un moment tu fais un test d'infériorité entre eux, ce que tu veux est en fait de savoir si < est défini, non s'ils sont numériques. Par exemple, avec le code du dessus, tu zapperais dans un tel cas les classes qui ont éventuellement overloadé un operator <, mais pas avec boost :

#include    <iostream>
#include    <limits>
#include    <boost/concept_check.hpp>
#include    <boost/concept/requires.hpp>

namespace test
{
    struct Dummy {};

    template <class T>
    BOOST_CONCEPT_REQUIRES
    ((( boost::LessThanComparable<T> )), (void))
    MaFonction(const T ArgUn, const T ArgDeux)
    {
        if ( ArgUn < ArgDeux )
            std::cout    << ArgUn << " est plus petit que " << ArgDeux << std::endl;
        else
            std::cout    << ArgUn << " n'est pas plus petit que " << ArgDeux << std::endl;
    }
}

int main()
{
    test::MaFonction(0, 2);
    test::MaFonction(1.2, 0.6);
    test::MaFonction(std::string("Zero"), std::string("Un"));
//test::MaFonction(test::Dummy(), test::Dummy());
    return 0;
}

Donne :

0 est plus petit que 2
1.2 n'est pas plus petit que 0.6
Zero n'est pas plus petit que Un

Mais en décommentant la dernière ligne, à la compilation :

/home/ether/a/b.cpp: In function ‘typename boost::Requires_<(0 + boost::_requires_<void (*)(boost::LessThanComparable<TT>)>::value), void (*)()>::type test::MaFonction(T, T) [with T = test::Dummy, typename boost::Requires_<(0 + boost::_requires_<void (*)(boost::LessThanComparable<TT>)>::value), void (*)()>::type = void]’:
/home/ether/a/b.cpp:28:47:   instantiated from here
/home/ether/a/b.cpp:16:3: error: no match for ‘operator<’ in ‘ArgUn < ArgDeux’
...blablabla templates blablabla...
In file included from /home/ether/a/b.cpp:4:0:
/usr/include/boost/concept_check.hpp: In destructor ‘boost::LessThanComparable<TT>::~LessThanComparable() [with TT = test::Dummy]’:
/usr/include/boost/concept/detail/general.hpp:38:28:   instantiated from ‘static void boost::concepts::requirement<boost::concepts::failed************ Model::************>::failed() [with Model = boost::LessThanComparable<test::Dummy>]’
/usr/include/boost/concept/requires.hpp:31:1:   instantiated from ‘boost::_requires_<void (*)(boost::LessThanComparable<test::Dummy>)>’
/home/ether/a/b.cpp:28:47:   instantiated from here
/usr/include/boost/concept_check.hpp:242:7: error: no match for ‘operator<’ in ‘((boost::LessThanComparable<test::Dummy>*)this)->boost::LessThanComparable<test::Dummy>::a < ((boost::LessThanComparable<test::Dummy>*)this)->boost::LessThanComparable<test::Dummy>::b’

Dernière modification par ehmicky (Le 20/08/2011, à 20:55)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#3 Le 20/08/2011, à 21:00

helly

Re : [résolu]C++, type numérique

Ha tiens, ça marche avec is_specialized ? oO
J’vais revoir ça alors.
Pour boost, bof, je cherche plutôt une solution dans la STL.


Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.

Hors ligne

#4 Le 20/08/2011, à 21:37

helly

Re : [résolu]C++, type numérique

Bon, j’ai eu une autre réponse qui me convient mieux, et qui utilise la STL smile.
Soit utiliser les typeinfo :

template <typename T>
bool is_numeric()
{
return (typeid(T) == typeid(short) || typeid(T) == typeid(int) || …);
}

Ou via les « classes de traits »

template <typename T>
struct is_numeric
{
static const bool value = false;
}

template <>
struct is_numeric<short>
{
static const bool value = true;
}

template <>
struct is_numeric<int>
{
static const bool value = true;
}
…

Avec une préférence pour la seconde qui est quand même plus propre smile.
Il n’y a visiblement pas plus simple en STL.

Dernière modification par helly (Le 20/08/2011, à 21:47)


Archlinux-wmii-dwb.
Un problème résolu ? Faites le savoir en mettant [résolu] à côté du titre de votre topic.
Un problème non résolu ? Faites le savoir en insultant ceux qui cherchent à vous aider.
Un site bleu super remasterised©, un wiki cherchant des volontaires pour traduire un site.

Hors ligne

#5 Le 24/08/2011, à 13:31

Luc Hermitte

Re : [résolu]C++, type numérique

boost, c'est un peu l'arrière court de la SL. N'aie pas de scrupules à t'en servir.
Sinon, les tests plus poussés seront dans la SL du C++11.

Hors ligne

#6 Le 12/11/2011, à 01:20

ehmicky

Re : [résolu]C++, type numérique

Déterrage, je me disais qu'avec numeric_limits, on court le risque que le client spécialise numeric_limits. Donc, il y a aussi :

#include    <boost/type_traits.hpp>
...
boost::is_arithmetic<type>::value

(Ou std:: si tu supportes c++11)
Ca évite de multiplier le code pour l'ensemble des types builtins.

Dernière modification par ehmicky (Le 12/11/2011, à 01:28)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne