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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

[valarray] Créer une classe de vecteur 3D


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 58
    Par défaut [valarray] Créer une classe de vecteur 3D
    Bonjour à tous !

    Dernièrement, lors d'un stage, j'ai dû coder une classe représentant des vecteurs tridimensionnelles. Je l'ai codé en dérivant la classe valarray de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #ifndef VECTOR3D_HPP
    #define VECTOR3D_HPP
     
    #include <valarray>
    #include <ostream>
    #include <cmath>
     
    template <typename T>
    struct Vector3D : public std::valarray<T>
    {
    	Vector3D() : std::valarray<T>(static_cast<T>(0), 3) {}
    	Vector3D(T x, T y, T z) : std::valarray<T>({x,y,z}) {} //C++0x
     
    	T norm() const { return std::sqrt(((*this)*(*this)).sum()); }
    	T norm2() const { return ((*this)*(*this)).sum(); }
     
    };
     
    template <typename T>
    std::ostream& operator<<(std::ostream& out, const std::valarray<T>& v)
    {
    	const size_t end(v.size()-1);
    	for(size_t i(0); i < end; ++i)
    		out << v[i] << ' ';
    	out << v[end];
    	return out;
    }
     
    typedef Vector3D<double> Vect3d;
    typedef Vector3D<int> Vect3i;
     
    #endif
    Avec ce code, je retrouve toutes les opérations importantes des vecteurs. Cependant les codes suivants ne marchent pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
    #include "Vector3D.hpp"
     
    using namespace std;
     
    int main()
    {
    	Vect3d v(1,2,3);
    	cout <<  v*v << '\n'; // Erreur de syntaxe 
    	return 0;
    }
    Il y a une erreur au niveau de l'affichage dans la console et je ne vois vraiment pas d'où ça vient. Savez-vous d'où vient le problème sachant que le message d'erreur est le suivant?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     g++ main.cpp -o vector3d -std=c++0x
    main.cpp: In function ‘int main()’:
    main.cpp:9: erreur: no match foroperator<<’ in ‘std::cout << std::operator* [with _Tp = double](((const std::valarray<double>&)((const std::valarray<double>*)(& v.Vector3D<double>::<anonymous>))), ((const std::valarray<double>&)((const std::valarray<double>*)(& v.Vector3D<double>::<anonymous>))))’
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:108: note: candidats sont: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& (*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:117: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT, _Traits>& (*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:127: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:165: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:169: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:173: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/ostream.tcc:91: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:180: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/ostream.tcc:105: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:191: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:200: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:204: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:209: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:213: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:221: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/ostream:225: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/ostream.tcc:119: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/valarray_after.h:409: note:                 std::_Expr<std::_BinClos<std::__shift_left, std::_Constant, std::_Expr, typename _Dom::value_type, _Dom>, typename std::__fun<std::__shift_left, typename _Dom1::value_type>::result_type> std::operator<<(const typename _Dom::value_type&, const std::_Expr<_Dom1, typename _Dom1::value_type>&) [with _Dom = std::_BinClos<std::__multiplies, std::_ValArray, std::_ValArray, double, double>]
    Merci de votre aide !

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Bonjour,

    Tout d'abord, je ne suis pas certain qu'utiliser valarray pour ça soit une très bonne idée. Bien sur, les opérations de base existent, mais la supposition de travail des valarrays est qu'ils vont être d'assez grande taille, et utilisent l'allocation dynamique. Pour des tableaux de taille fixe et faible, allouer la mémoire non dynamiquement peut être un avantage énorme et terme de perfs.

    Utiliser un truc à base de std::array (ou tr1::array ou boost::array, selon l'âge de ton compilo) serait surement mieux. Ou carrément utiliser une bibliothèque prévue pour (Eigen semble avoir pas mal la cotte en ce moment).

    Ensuite, pour ton problème, il dit simplement qu'il ne sait pas comment afficher ta classe, rien n'est prévu pour l'affichage des valarrays, je crois. A toi de définir un opérateur << si tu veux faire ça.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2006
    Messages : 58
    Par défaut
    Tout d'abord, je ne suis pas certain qu'utiliser valarray pour ça soit une très bonne idée. Bien sur, les opérations de base existent, mais la supposition de travail des valarrays est qu'ils vont être d'assez grande taille, et utilisent l'allocation dynamique. Pour des tableaux de taille fixe et faible, allouer la mémoire non dynamiquement peut être un avantage énorme et terme de perfs.
    Exactement, on m'avait fait la même critique aussi. C'est sympa d'avoir confirmé la remarque. Je vais jeter un coup d'oeil à Eigen. Je suis sûr d'avoir quelque chose de performant avec. Mais je ne vois pas pourquoi avec des tableaux de taille fixe et faible cela est moins performant? Auriez-vous une explication plus approfondie?

    Ensuite, pour ton problème, il dit simplement qu'il ne sait pas comment afficher ta classe, rien n'est prévu pour l'affichage des valarrays, je crois. A toi de définir un opérateur << si tu veux faire ça.
    Mais justement je l'ai défini :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template <typename T>
    std::ostream& operator<<(std::ostream& out, const std::valarray<T>& v)
    {
    	const size_t end(v.size()-1);
    	for(size_t i(0); i < end; ++i)
    		out << v[i] << ' ';
    	out << v[end];
    	return out;
    }
    Merci beaucoup de ta réponse; c'est exactement ce que je cherchais !

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Désolé, je n'avais pas scrollé la première fenêtre de code...

    Et ton code compile chez moi (VC2010).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    De plus hérité publiquement de valarray c'est pas une bonne idée... (pas de dtor virtuel)

Discussions similaires

  1. Réponses: 40
    Dernier message: 21/06/2007, 17h58
  2. Réponses: 14
    Dernier message: 28/02/2007, 09h53
  3. Réponses: 1
    Dernier message: 09/02/2007, 12h28
  4. Créer une classe commune à +sieurs fiches
    Par rtg57 dans le forum C++Builder
    Réponses: 2
    Dernier message: 08/05/2006, 17h58
  5. Réponses: 4
    Dernier message: 08/10/2005, 09h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo