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

C++ Discussion :

[c++11] Probl�me : fonction retournant un std::array. (A 2 dimensions)


Sujet :

C++

  1. #1
    Invit�
    Invit�(e)
    Par d�faut [c++11] Probl�me : fonction retournant un std::array. (A 2 dimensions)
    Salut!

    Je suis entrain de faire une classe qui recherche les minimums et maximums en x, y et z d'un ensemble de vecteurs et qui les stocke dans un std::array � 2 dimension. (1�re dimension pour l'axe et seconde dimension pour les mins et maxs pour chaque axe)

    Jusque l� pas de soucis :

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
     template <std::size_t N>
        static std::array<std::array<float, 3>,2> getExtends (const std::array<Vec3f, N>& verts) {
            float minX = 0;
            float maxX = 0;
            float minY = 0;
            float maxY = 0;
            float minZ = 0;
            float maxZ = 0;
            if (verts.size() > 0) {
                minX = verts[0].x;
                maxX = verts[0].y;
                minY = verts[0].x;
                maxY = verts[0].y;
                minZ = verts[0].z;
                maxZ = verts[0].z;
            }
            std::array<std::array<float, 3>, 2> store;
            for (unsigned int i(1); i < verts.size(); i++) {
     
     
                    if (verts[i].x > maxX) {
                        maxX = verts[i].x;
                    }
                    if (verts[i].x < minX) {
                        minX = verts[i].x;
                    }
                    if (verts[i].y > maxY) {
                        maxY = verts[i].y;
                    }
                    if (verts[i].y < minY) {
                        minY = verts[i].y;
                    }
                    if (verts[i].z > maxZ) {
                        maxZ = verts[i].z;
                    }
                    if (verts[i].z < minZ) {
                        minZ = verts[i].z;
                    }
     
     
            }
            store[0][0] = minX;
            store[0][1] = maxX;
            store[1][0] = minY;
            store[1][1] = maxY;
            store[2][0] = minZ;
            store[2][1] = maxZ;
            std::cout<<"min x : "<<store[0][0]<<" max x : "<<store[0][1]<<" minY = "<<store[1][0]<<" maxY : "<<store[1][1]<<" min Z : "<<store[2][0]<<" max Z : "<<store[2][1]<<std::endl;
            return store;
        }
    J'ai une bo�te de position 200, 200, 0 et de taille 120, 110, 0 et j'ai bien c'est valeurs-ci pour store[axe][borne] : (voici ce qu'il m'affiche)

    minX : 200 maX : 320 minY : 200 maxY : 310 minZ : 0 maxZ : 0.

    Le probl�me survient lorsque je r�cup�re ce tableau dans une autre fonction, les valeurs ne sont alors plus bonne pour z :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
     
    store = Computer::getExtends(points);
        std::cout<<"min x : "<<store[0][0]<<" max x : "<<store[0][1]<<" minY = "<<store[1][0]<<" maxY : "<<store[1][1]<<" min Z : "<<store[2][0]<<" max Z : "<<store[2][1]<<std::endl;
    Voici ce qu'il m'afficher :

    minX : 200 maX : 320 minY : 200 maxY : 310 minZ : 200 maxZ : 250.

    Voila merci d'avance pour l'aide.

  2. #2
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de caf�
    Inscrit en
    Mai 2007
    Messages
    1 048
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 39
    Localisation : France

    Informations professionnelles :
    Activit� : Consommateur de caf�
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par d�faut
    Bonjour,

    Ne retourne jamais un conteneur standard par valeur!
    Passes le en r�f�rence � ta fonction, puis modifies cette r�f�rence. Ca devrait te donner ceci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    static void getExtends (const std::array<Vec3f, N>& verts,std::array<std::array<float, 3>,2>& minmax)
    De plus, cela devrait peut �tre r�gler ton probl�me vu que ta fonction est static et que tu d�clares toujours ton std::array dans cette fonction.

  3. #3
    Invit�
    Invit�(e)
    Par d�faut
    Bonjour,

    Attention aux indices, tu as ceci std::array<std::array<float, 3>,2> : soit 2 tableaux de 3 float et non l'inverse !
    D'apr�s tes lignes store[][] = ..., tu dois inverser le 2 et le 3.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    D�tails du profil
    Informations personnelles :
    Localisation : France, Paris (�le de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par d�faut
    Winjerome a s�rement vu juste !

    Citation Envoy� par Astraya Voir le message
    Ne retourne jamais un conteneur standard par valeur !
    Pas d'accord ! Avec la s�mantique de d�placement, c'est tout � fait correct de le faire. Surtout qu'on est dans un sujet explicitement C++11.

  5. #5
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de caf�
    Inscrit en
    Mai 2007
    Messages
    1 048
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 39
    Localisation : France

    Informations professionnelles :
    Activit� : Consommateur de caf�
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par d�faut
    Pas d'accord ! Avec la s�mantique de d�placement, c'est tout � fait correct de le faire. Surtout qu'on est dans un sujet explicitement C++11.
    Oui avec la s�mantique de d�placement, mais qui oblige le compilateur � respecter cette r�gle? Le font-il tous? Pour le moment, je suis encore partisan de ne pas toujours utiliser les solutions C++11, juste parce que les compilateurs n'ont pas le m�me comportement ni �volution sur l'impl�mentation du C++11. Imagions que l'on prend l'habitude en apprenant le C++ de faire �a. Que se passe-t-il lorsque l'on passe sur un projet assez vieux qui ne supporte pas le C++11? Les r�flexes ont la vie dure et vaut mieux avoir les bons je pense.

    Enfin c'est un avis personnel et �a n'engage que moi

  6. #6
    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 : 51
    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
    Avec la move semantic, on peut retourner un conteneur de la stl par valeur sans soucis ni risque... Sauf peut-�tre std::array, qu'on ne peut pas d�placer de mani�re efficace (c'est le prix � payer pour ne pas avoir d'indirection ou d'allocation). Maintenant, la rvo ou nrvo marchera peut-�tre quand m�me, et dans ce cas le retour sera plus efficace que la passage en param�tres (qui va forcer l'initialisation � une mauvaise valeur). Et m�me sans �a, pour un array de taille raisonnable, ce n'est pas �vident de voir une diff�rence. Mais je tenais � signaler ce point quand m�me. Je dirais que seule la mesure pourra donner une bonne information.
    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.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    D�tails du profil
    Informations personnelles :
    Localisation : France, Paris (�le de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par d�faut
    Citation Envoy� par Astraya Voir le message
    Oui avec la s�mantique de d�placement, mais qui oblige le compilateur � respecter cette r�gle? Le font-il tous? Pour le moment, je suis encore partisan de ne pas toujours utiliser les solutions C++11, juste parce que les compilateurs n'ont pas le m�me comportement ni �volution sur l'impl�mentation du C++11.
    La norme est l� pour �a . La plupart des compilateurs du march� sont assez bien avanc�s sur le C++11, et cela inclue la s�mantique de d�placement. Pour moi, cela fait partie du travail du d�veloppeur de savoir ce que son compilateur impl�mente correctement ou pas.

    Quant � faire des mesures pour voir ce qui est plus efficace : oui, � condition qu'on soit dans une phase d'optimisation, ce qui ne semble pas �tre le cas ici. Je dirais qu'on est encore dans la phase ou l'on �crit le code le plus expressif possible.

  8. #8
    Invit�
    Invit�(e)
    Par d�faut
    Mon compilateur est un tdm-gcc 4.8.1. (32 bits)
    Je pense qu'il supporte bien les fonctionnalit�s du c++11 donc.

    J'ai du faire un erreur dans les indices car pour des tableaux 2*2 �a marche sans probl�me.

    PS : ha oui en effet c'est std::array<std::array<float, 2> 3> et pas std::array<std::array<float, 3> 2> (je confond toujours)

    Probl�me r�solu, merci.
    Derni�re modification par Invit� ; 14/04/2014 � 15h24.

  9. #9
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de caf�
    Inscrit en
    Mai 2007
    Messages
    1 048
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 39
    Localisation : France

    Informations professionnelles :
    Activit� : Consommateur de caf�
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par d�faut
    Je ne dis pas de ne pas utiliser le move alors que l'on pourrais l'utiliser.
    Mais avant tout, il est bon de savoir si le compilateur est capable de le faire.
    Car oui il y a des versions de gcc qui ne le font pas. Des versions customs, comme pour les consoles de salon par exemple, et la bas le code ne fonctionne plus.
    Ou alors pour de l'embarqu� avec une version qui ne l'int�gre pas etc..
    Donc la NRVO n'est pas une panac�e existant partout et � toujours utiliser.

    Mais c'est quand m�me une fonctionnalit� cool, je dis pas le contraire.

  10. #10
    Membre �prouv�
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par d�faut
    En tout cas, on est loin de :

    Citation Envoy� par Astraya Voir le message
    Ne retourne jamais un conteneur standard par valeur

  11. #11
    Membre �m�rite
    Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Par d�faut
    Bonjour,

    Pour tout ce qui est calcul d'enveloppe/bbox/extent, il y a une principe assez pratique qui revient dans de nombreuses biblioth�ques : expandToInclude

    Je profite du sujet pour me mettre � jour sur C++11 et voir comment je pourrais mettre � jour certains codes. Voici ce que �a donnerait sur mes stocks :

    * Un interval au sens [lower,upper] :

    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
    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
     
    template < typename T >
    class Interval {
    public:
    	typedef T value_type ;
     
    	static_assert( std::numeric_limits< value_type >::has_quiet_NaN, "T doit posséder le concept de NaN (gestion de empty)" ) ;
     
    	Interval():
    		_lower( std::numeric_limits< value_type >::quiet_NaN() ),
    		_upper( std::numeric_limits< value_type >::quiet_NaN() )
    	{
    	}
     
    	Interval( const value_type & value ):
    		_lower( value ),
    		_upper( value )
    	{
    	}
     
    	Interval( const value_type & v1, const value_type& v2 ):
    		_lower( std::min(v1,v2) ),
    		_upper( std::max(v1,v2) )
    	{
    	}
     
    	void expandToInclude( const value_type & v ) {
    		if ( isEmpty() ){
    			_lower = v ;
    			_upper = v ;
    		}else if ( ! isNaN(v) ){
    			_lower = std::min( _lower, v ) ;
    			_upper = std::max( _upper, v ) ;			
    		}
    	}
     
    	void expandToInclude( const Interval & other ) {
    		expandToInclude( other.lower() ) ;
    		expandToInclude( other.upper() ) ;
    	}
     
    	bool isEmpty() const {
    		return isNaN(_lower) ; 
    	}
     
    	const value_type & lower() const {
    		return _lower; 
    	}
     
    	const value_type & upper() const {
    		return _upper; 
    	}
     
    private:
    	value_type _lower ;
    	value_type _upper ;
    };
    * Une Box d�finie par des Interval sur les diff�rentes dimensions

    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
     
    template < typename T, unsigned int N >
    class Box {
    public:
    	typedef Interval< T >    interval_type ;
    	typedef std::array<T,N>  vector_type ;
     
    	void expandToInclude( const vector_type & v ) {
    		for ( size_t i = 0; i < N; i++ ){
    			_bounds[i].expandToInclude( v[i] ) ; 
    		}
    	}
     
    	const interval_type & operator [] ( const unsigned int & i ) const {
    		return _bounds[i];
    	}
    	interval_type & operator [] ( const unsigned int & i ) {
    		return _bounds[i];
    	}
     
    private:
    	std::array< interval_type, N > _bounds ;
    };
    * Exemple d'utilisation

    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
     
    typedef std::array<float,3> Vec3f ;
    typedef Box<float,3>         Box3f ;
     
    typedef Box<int,3>            Box3i ;
     
    int main(){
    	std::vector< Vec3f > points = {
    		{1.0f,3.0f,6.0f},
    		{3.0f,2.0f,8.0f}
    	} ;
     
    	Box3f box ;
    	for ( const Vec3f & point : points ){
    		box.expandToInclude( point ) ;
    	}
    	std::cout << "xmin, ymin, zmin : " ;
    	std::cout << box[0].lower() << " " << box[1].lower() << " " << box[2].lower() << std::endl;
     
    	std::cout << "xmax, ymax, zmax : " ;
    	std::cout << box[0].upper() << " " << box[1].upper() << " " << box[2].upper() << std::endl;	
     
    	return 0 ;
    }
    PS :
    - Tu peux supporter des "expandToInclude" avec des vecteurs de dimension inf�rieure � celle de la boite
    - Tu peux raffiner avec des "Box::expandToInclude(other: Box)"
    - Pour le isNaN, je n'ai rien de mieux que �a de mon c�t�...

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    template < typename T >
    bool isNaN( const T& value ){
    	return value != value ; 
    }

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 5
    Dernier message: 31/01/2008, 08h34
  2. Probl�me fonction retournant type complexe.
    Par mihaestii dans le forum SQL
    R�ponses: 3
    Dernier message: 27/08/2007, 14h33
  3. R�ponses: 22
    Dernier message: 06/11/2006, 19h31
  4. R�ponses: 6
    Dernier message: 14/02/2006, 11h29

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