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 :

Convertion std::wstring en char*


Sujet :

SL & STL C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 71
    Points : 34
    Points
    34
    Par défaut Convertion std::wstring en char*
    Bonjour,

    J'aimerais savoir comment convertir simplement un wstring en char*.

    Merci.

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 71
    Points : 34
    Points
    34
    Par défaut
    Merci.
    J'ai ajouter les fonctions à mon projet dans un fichier Tool.h
    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
    #include <string>
    #include <locale>
     
     
    namespace Tool {
     
    	std::string WStringToString(const std::wstring& ws)
    	{
    		std::string res(ws);
    		std::locale loc("english");
    		std::use_facet< std::ctype<wchar_t> >(loc).narrow(&ws[0], &ws[ws.length()], '?', &res[0]);
     
    		return res;
    	}
     
    	std::wstring StringToWString(const std::string& s)
    	{
    		std::wstring res(s);
    		std::locale loc("english");
    		std::use_facet< std::ctype<wchar_t> >(loc).widen(&s[0], &s[s.length()], &res[0]);
     
    		return res;
    	}
     
    }
    et j'ai l'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Erreur	1	tool.h	9	error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it)' : impossible de convertir le paramètre 1 de 'const std::wstring' en 'std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it'
    Erreur	2	tool.h	18	error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it)' : impossible de convertir le paramètre 1 de 'const std::string' en 'std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it'
    Pourquoi ?

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par pegase06 Voir le message
    Elle est bien étrange, cette prise d'adresse. Tu références un élément qui n'existe pas pour en prendre l'adresse. J'aurais plutôt fait: .

    Cela ne règle pas ton problème, mais c'est déjà un petit plus.

    Carl

  5. #5
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut 3 erreurs/3 lignes
    Citation Envoyé par pegase06 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	std::string WStringToString(const std::wstring& ws)
    	{
    		std::string res(ws);
    		std::locale loc("english");
    		std::use_facet< std::ctype<wchar_t> >(loc).narrow(&ws[0], &ws[ws.length()], '?', &res[0]);
     
    		return res;
    	}
    }
    Pourquoi ?
    Pourquoi 3 erreurs en 3 lignes, telle est la question.

    Reprenons :

    std::string res(ws);

    Déjà, ça ne risque pas de compiler. Une chaine de char n'est pas une chaine de wchar_t. Probablement fallait-il lire

    std::string res(ws.size());

    puisque de toutes façons le contenu sera effacé, il faut juste créer les caractères à écraser.

    std::locale loc("english");

    Qui dit qu'une telle locale existe? Sur un système Un*x, je ne pense pas que risque d'être le cas. Peut-être une locale "en" existera t-elle, mais en quoi en avons nous besoin?

    Surtout que doit faire une telle "locale"? La "locale" devrait regrouper les caractéristiques locales. En quoi les facets ctype et codecvt sont-elles des propriétés locales (= préférences régionales)? En rien évidemment. Ce sont des caractéristiques de jeux de caractères. Bien sûr, ISO-8859-5 ne permet pas d'écrire le français, et "donc" ne se trouvera pas dans une locale française ("fr", "fr_FR", "french"...). Mais, en réalité, ISO-8859-1 non plus. La relation entre locale et jeu de caractères est complexe et dépendant de l'histoire. On trouve d'ailleurs des locales appelée "fr.utf8". Ridicule.

    Cette absurdité prend racine quelque part dans Unix. C++ a suivit dans la voie du non-sens et de l'inutilisable, évidemment.

    En résumé : le nom des locales est dépendant du système et, en terme de jeu de caractère, sa signification peu claire. De toutes façons, le jeu de caractère est une propriété d'un ressource (fichier, flux, chaine...), pas d'une région/culture (mais un utilisateur peut typiquement avoir un codage préféré pour les fichiers de sortie).

    Ici, la ressource en entrée est une chaine large, donc normalement composée de code-point Unicode : UCS-2 ou UCS-4. (Mais on risque aussi de trouver de l'UTF-16. Beurk. Encore une question à préciser.) Le codage est donc à peu-près clair (nous verrons que non, pas tout à fait).

    En sortie par contre, il faudrait définir le jeu de caractère à utiliser : est-ce défini par un protocole (= une norme), par le concepteur du programme, ou par la préférence de l'utilisateur (seul cas où une locale me semble adéquate). Pour les sorties, une variable d'environnement spécifique (qui n'influe pas les autres paramètres de localisation), ou une option en ligne de commande est souvent le seul réglage suffisamment flexible pour s'adapter aux différences de jeux de caractères.

    Enfin, si la locale "english" signifie comme je le pense "iso-latin-1", la conversion est triviale :

    c = wc < 256 : (char)wc : '?';

    En effet les valeurs Unicode correspondent intentionnellement à iso-latin-1, pour la bonne notion de correspondance : encore faut-il être en forme NFC (ou NFKC...), c'est à dire qu'une lettre doit être décrite par un seul code-point, par exemple : "à" doit être codée LATIN SMALL LETTER A WITH GRAVE et non LATIN SMALL LETTER A suivit de COMBINING GRAVE ACCENT.

    Je ne sais pas ce que font les implémentations de codecvt des formes D (LATIN SMALL LETTER A suivit de COMBINING ACUTE ACCENT) mais la norme dit bien qu'elles n'ont pas à les gérer, pas plus qu'un wchar_t en UTF-16 (puisque la représentation interne ne doit pas avoir plusieurs "éléments" (wchar_t) pour une séquence d'éléments externes, représentant une lettre). Manifestement, ce genre de choses n'est pas prévu, pour preuve l'interface utilisée ici : narrow.

    Je mentionne ça en passant, il faut s'assurer quand on parle de wstring si :
    - il s'agit bien d'UCS-* (comme on l'attend pour une représentation interne) ou d'UTF-16 (comme Java, assez hypocritement)
    - on exige la forme NFC (forme "courte"), NFD, ou n'importe; mais très franchement les diacritiques combinant sont une débilité sans nom inventée par Unicode, je n'imagine pas que votre code soit compatible avec ça (en faisant quelque traitement - autre que lire un chaine recopier la chaine) (les code-point combinant Unicode DOIVENT MOURIR, faites passer le mot) (reste qu'ils ne sont pas encore mort - et à peine nés)

    En général on fait les deux hypothèses ci-dessus sans le dire, mais c'est quand même un beau bordel (et passablement hypocrite aussi).

    Dans la ligne :

    std::use_facet< std::ctype<wchar_t> >(loc).narrow(&ws[0], &ws[ws.length()], '?', &res[0]);

    2 erreurs

    &ws[0], &ws[ws.length()]

    Il n'est pas garanti que la représentation d'une string soit contigüe (contrairement à vector).

    &res[0]

    Même problème, il n'est pas garanti que &res[0], &res[0] + res.size() soit une range valide.

    En plus, &ws[ws.length()] désigne un NUL à la fin de la chaine uniquement parce que ws est const. C'est une idée hyper-vicieuse de la norme et c'est hyper-dangereux : si, dans une évolution future du programme, ws devenait non-const (par exemple, si ça devenait une variable locale de la fonction), le code casserai, silencieusement.

    Non seulement c'est immensément crétin de la part de la norme de différencier const/non-const comme ça, en plus, la description ne veut rien dire :

    the const version returns charT()

    D'après la norme, cette fonction renvoie une référence sur un temporaire! Lapsus normatif? (genre, je ne spécifie pas du tout ce qui est immonde (vector<bool>), ou alors n'importe comment (ici)).

    Fonctionnalité à éviter absolument en tous cas. La surcharge de const ne sert part à ça! (quelque fois, la lib standard ne comprend comment les fonctionnalités du C++ sont censées être utilisées)

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 380
    Points : 41 576
    Points
    41 576
    Par défaut
    Il me semblait bien que ce code était mauvais quand je l'ai vu dans la FAQ.

    Si je me souviens bien, la norme définit seulement deux noms de locale: "C" et "" (chaîne vide).
    Ensuite, les auteurs de la SL se sont bien débrouillés pour qu'il n'y ait absolument aucun moyen d'obtenir un accès direct en écriture sur le buffer d'une std::string (contrairement à ceux de MFC qui proposent CString::GetBuffer()).

    Donc, si je comprends bien, il est:
    • D'une part, impossible de convertir en un seule passe une string en wstring avec un seul appel de narrow() (on doit faire des append() successifs, ou passer par un buffer),
    • D'autre part, impossible de spécifier de manière portable une locale (mais "" devrait suffire dans la plupart des cas).

  7. #7
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Donc, si je comprends bien, il est:
    • D'une part, impossible de convertir en un seule passe une string en wstring avec un seul appel de narrow() (on doit faire des append() successifs, ou passer par un buffer),
    narrow c'est un appel virtuel (à l'intérieur), je doute que tu veuille faire un appel par caractère!

    Ceci vaut aussi pour ctype<charT>, codecvt. On accumule quelques caractères dans un buffer avant d'appliquer l'opération (virtuelle). C'est aussi le principe de streambuf. Le buffer va typiquement être de taille fixe, et l'opération répétée en boucle (donc ça n'induit aucune limite sur la quantité de données traitées).

    Note : Il ne faut pas dramatiser le coup des fonctions virtuelles. Juste que par rapport à convertir ou classifier 1 caractère, c'est monstrueusement couteux. (Non, je ne vais pas m'amuser à faire des tests pour le prouver.)

    Encore une fois, si c'est pour convertir de UCS-* (NFC) en ISO-8859-1, il y a plus simple (et efficace et fiable)!

    (Encore une fois, si ce n'est pas du NFC (ou NFKC...), la bibliothèque standard n'est pas utilisable. Si tu importes de l'Unicode de l'extérieur, fais attention à ça.)

  8. #8
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par corrector Voir le message
    Il n'est pas garanti que la représentation d'une string soit contigüe (contrairement à vector).
    En pratique, et pour le futur, c'est garanti :
    http://www.open-std.org/jtc1/sc22/wg...fects.html#530

    Edit : La partie indentée de ce message est n'importe quoi. Merci de n'en pas tenir compte.
    Citation Envoyé par corrector Voir le message
    the const version returns charT()

    D'après la norme, cette fonction renvoie une référence sur un temporaire! Lapsus normatif? (genre, je ne spécifie pas du tout ce qui est immonde (vector<bool>), ou alors n'importe comment (ici)).

    Fonctionnalité à éviter absolument en tous cas. La surcharge de const ne sert part à ça! (quelque fois, la lib standard ne comprend comment les fonctionnalités du C++ sont censées être utilisées)
    Il semble qu'elle connaisse tout de même un peu le langage...
    Citation Envoyé par Le standard, 12.2.5
    The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below.
    Fin d'édit

    Pour le vector<bool>, qu'est-ce qui n'est pas spécifié ? Pour moi, ils ont voulu trop spécifier justement, et c'est tombé à côté...

  9. #9
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    En pratique, et pour le futur, c'est garanti :
    http://www.open-std.org/jtc1/sc22/wg...fects.html#530
    Précisément, non :

    Proposed resolution:

    Add the following text to the end of 21.3 [basic.string], paragraph 2.

    The characters in a string are stored contiguously, meaning that if s is a basic_string<charT, Allocator>, then it obeys the identity &*(s.begin() + n) == &*s.begin() + n for all 0 <= n < s.size().

    Le NUL terminal n'est pas in la chaine et ws.length() n'est pas strictement inférieur à ws.size(), donc &ws[0], &ws[ws.length()] n'est pas une range valide, et la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::use_facet< std::ctype<wchar_t> >(loc).narrow(&ws[0], &ws[ws.length()], '?', &res[0]);
    est incorrecte.

    Citation Envoyé par JolyLoic Voir le message
    Il semble qu'elle connaisse tout de même un peu le langage...
    Je ne pense pas. Et je ne comprends pas ce que tu dis : est-ce que tu penses que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const int &f () {
      return int();
    }
    est correct?

    La norme (je prends le dernier draft n2521) n'est pas de cet avis, dans le paragraphe que tu cites, 12.2/5 (pas 12.2.5) :
    The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except as specified below. (...) A temporary bound to the returned value in a function return statement (6.6.3) persists until the function exits.
    En dehors de la tournure très surprenante ("A temporary bound to a reference", répété plusieurs fois, alors que le paragraphe commence par "a reference is bound to a temporary", ce qui est la terminologie normale), il me semble très clair. Si ce n'est pas assez clair, quelque chose comme cela devrai être écrit :

    When a reference return value is bound to a temporary, the temporary persists until the function exits.

    (J'ai du relire plusieurs fois la phrase originale; quelle idée d'écrire comme ça? Savent-ils écrire en anglais?)

    Citation Envoyé par JolyLoic Voir le message
    Pour le vector<bool>, qu'est-ce qui n'est pas spécifié ? Pour moi, ils ont voulu trop spécifier justement, et c'est tombé à côté...
    Justement, dans la norme, rien, à part des déclarations. On ne sait pas ce à quoi sert reference::flip(). Comme il n'y a aucune relation explicitée entre vector<bool> et la forme de base de vector, on ne sait ce que fait aucune fonction membre.

  10. #10
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Citation Envoyé par corrector Voir le message
    Le NUL terminal n'est pas in la chaine et ws.length() n'est pas strictement inférieur à ws.size(), donc &ws[0], &ws[ws.length()] n'est pas une range valide, et la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::use_facet< std::ctype<wchar_t> >(loc).narrow(&ws[0], &ws[ws.length()], '?', &res[0]);
    est incorrecte.
    le problème n'est pas la présence du NULL terminal puisqu'une étendue de &ws[0] à &ws[ws.length()] va des éléments de 0 à ws.length()-1 (= ws.size()-1 ), le "end()" d'un itérateur à accès aléatoire pointant sur l'adresse de l'élément se trouvant juste APRES le dernier élément du tableau (élément auquel il ne faut bien sur pas tenter d'accéder). La seule crainte pourrait être que l'opérateur [] dans ws[ws.length()] vérifie que l'indice soit strictement plus petit que ws.length() (et lève une exception dans le cas contraire), mais cela m'étonnerais, surtout si cela est implémenté comme pour
    Clause 23.3.4 [multiset] defines operator[] as data()[pos]
    Il faudrait juste voir ce que défini la norme sur l'operateur [] pour les basic_string

  11. #11
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par gb_68 Voir le message
    La seule crainte pourrait être que l'opérateur [] dans ws[ws.length()] vérifie que l'indice soit strictement plus petit que ws.length() (et lève une exception dans le cas contraire), mais cela m'étonnerais, surtout si cela est implémenté comme pour...
    J'avais posé cette question y as quelque temps. Au final, la norme ne spécifie rien sur l'opérateur []. Il est donc possible d'y avoir un test. C'est ce que fait visual 2005... et non gcc


    Au final, comme l'entrée de la faq est fausse.
    Quel est donc la bonne solution??

  12. #12
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par gb_68 Voir le message
    le problème n'est pas la présence du NULL terminal
    (Tu voulais dire NUL, je suppose.) Je n'ai jamais parlé de la présence de NUL.

    Citation Envoyé par gb_68 Voir le message
    puisqu'une étendue de &ws[0] à &ws[ws.length()]
    Cette étendue (range) n'est pas valide, elle n'existe pas, comme je l'ai indiqué.

    Citation Envoyé par gb_68 Voir le message
    va des éléments de 0 à ws.length()-1 (= ws.size()-1 ),
    Elle ne va nul part puisqu'elle n'existe pas.

    Citation Envoyé par gb_68 Voir le message
    le "end()" d'un itérateur à accès aléatoire pointant sur l'adresse de l'élément se trouvant juste APRES le dernier élément du tableau (élément auquel il ne faut bien sur pas tenter d'accéder).
    Rappelons que le code est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::use_facet< std::ctype<wchar_t> >(loc).narrow(&ws[0], &ws[ws.length()], '?', &res[0]);
    Où vois-tu "end()"?
    Ou un même un itérateur "juste APRES le dernier élément" ("one-past-the-end")?

    Citation Envoyé par gb_68 Voir le message
    La seule crainte pourrait être que l'opérateur [] dans ws[ws.length()] vérifie que l'indice soit strictement plus petit que ws.length()
    Non, elle ne va pas faire cela parce que l'indice n'a pas à être strictement inférieur à ws.length(). L'expression &ws[ws.length()] est absolument légale, comme je l'ai indiqué (mais elle est aussi très fortement déconseillée).

    Clause 23.3.4 [multiset] defines operator[] as data()[pos]

    23.3.4 fait 4 pages! (je regarde n2315, là) Tu peux préciser?

    Et depuis quand multiset définit data()?

    Par contre, à la question : est-ce que string peut faire des vérifications de bornes dans operator[], la réponse est oui, bien sûr.

  13. #13
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Au final, la norme ne spécifie rien sur l'opérateur [].
    Comment ça? Si une fonction n'est pas spécifiée, on ne peut pas l'utiliser!

    Citation Envoyé par Mongaulois Voir le message
    Il est donc possible d'y avoir un test.
    Dès lors qu'une fonction exige que ses arguments soient dans un certain domaine, l'implémentation de la fonction peut bien évidemment le vérifier.

    Citation Envoyé par Mongaulois Voir le message
    C'est ce que fait visual 2005... et non gcc
    Tu es sûr que Visual C++ le fait toujours et pas simplement dans la configuration par défaut? Tu es sûr que la libc++ ne peut pas le faire avec les -D qui vont bien?

  14. #14
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Au final, comme l'entrée de la faq est fausse.
    Quel est donc la bonne solution??
    Solution : préciser la question.
    Qu'a t-on en entrée, que veut-on en sortie?
    Voir aussi mon premier message (#5) à propos d'UCS-*/UTF-16 et NFC/NFD.

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par corrector Voir le message
    Comment ça? Si une fonction n'est pas spécifiée, on ne peut pas l'utiliser!

    Dès lors qu'une fonction exige que ses arguments soient dans un certain domaine, l'implémentation de la fonction peut bien évidemment le vérifier.


    Tu es sûr que Visual C++ le fait toujours et pas simplement dans la configuration par défaut? Tu es sûr que la libc++ ne peut pas le faire avec les -D qui vont bien?
    Pour vector (a vérifier pour les autres), visual utilise un test, mais on peut le désactiver. Gcc n'en fait pas. Du moins dans les dernière source que j'ai regardé : visual 2005 et gcc 3.4
    Pour être plus précis,dans la norme, l'operateur [] ne spécifie pas si il doit y avoir ou non un test..

  16. #16
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Pour être plus précis,dans la norme, l'operateur [] ne spécifie pas si il doit y avoir ou non un test..
    Pour être encore plus précis, si les arguments d'une fonction ne sont pas dans son domaine, sauf mention contraire, le comportement est indéfini. Autrement dit, c'est une précondition : tu dois passer les bon arguments, dans le cas contraire, tu ne peux rien exiger parce que tu as rompu ton contrat.

  17. #17
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par corrector Voir le message
    Solution : préciser la question.
    Qu'a t-on en entrée, que veut-on en sortie?
    Voir aussi mon premier message (#5) à propos d'UCS-*/UTF-16 et NFC/NFD.
    J'ai bien lu est compris pourquoi tu dit que c'est faux.
    Ma question est comme corriger la FAQ.
    es ce réellement dépendant du codage unicode utilisé? et dans ce cas comment faire suivant le codage utilisé?
    ou y as t'il une solution général?

  18. #18
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par corrector Voir le message
    Pour être encore plus précis, si les arguments d'une fonction ne sont pas dans son domaine, sauf mention contraire, le comportement est indéfini. Autrement dit, c'est une précondition : tu dois passer les bon arguments, dans le cas contraire, tu ne peux rien exiger parce que tu as rompu ton contrat.
    Je ne sait pas si c'est le cas pour le vector.
    L'operateur [] est là (c'est ce que j'ai compris) pour avoir les même accès qu'un tableau C.

  19. #19
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par corrector Voir le message
    Précisément, non :
    Je parlais du fait que le stockage soit continu, comme sur un vecteur. Pour ce qui est de l'accès à &ws[ws.length()], on est d'accord sur le fait que ce soit une erreur. Ce serait aussi une erreur pour un vecteur, la bonne écriture étant &ws[0] + ws.size()

    Citation Envoyé par corrector Voir le message
    Je ne pense pas. Et je ne comprends pas ce que tu dis : est-ce que tu penses que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const int &f () {
      return int();
    }
    est correct?
    Non, j'ai dit n'importe quoi. On va mettre ça sur le dos de l'heure tardive.
    A tête un peu plus reposée, je dirais juste que c'est une notation pour indiquer que le fonction retourne une référence constante à un caractère nul. A l'implémentation de se débrouiller pour que ce soit une référence valide.
    Citation Envoyé par corrector Voir le message
    Justement, dans la norme, rien, à part des déclarations. On ne sait pas ce à quoi sert reference::flip(). Comme il n'y a aucune relation explicitée entre vector<bool> et la forme de base de vector, on ne sait ce que fait aucune fonction membre.
    Ils ont un peu amélioré ça dans le brouillon du prochain standard, mais pour moi et pour beaucoup, l'erreur est d'avoir spécialisé vector<bool>, tout simplement :
    Citation Envoyé par Le brouillon du standard
    Unless described below, all operations have the same requirements and semantics as the primary vector template, except that operations dealing with the bool value type map to bit values in the container storage.
    3 There is no requirement that the data be stored as a contiguous allocation of bool values. A space-optimized representation of bits is recommended instead.
    4 reference is a class that simulates the behavior of references of a single bit in vector<bool>. The conversion operator returns true when the bit is set, and false otherwise. The assignment operator sets the bit when the argument
    is (convertible to) true and clears it otherwise. flip reverses the state of the bit.
    void flip();
    5 Effects: Replaces each element in the container with its complement. It is unspecified whether the function has any effect on allocated but unused bits.

  20. #20
    Provisoirement toléré
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Je parlais du fait que le stockage soit continu, comme sur un vecteur. Pour ce qui est de l'accès à &ws[ws.length()], on est d'accord sur le fait que ce soit une erreur. Ce serait aussi une erreur pour un vecteur, la bonne écriture étant &ws[0] + ws.size()
    Je préfère ws.data() + ws.size(), ça marche même si wc est vide.
    Dans le brouillon de norme N2315, data est aussi défini pour vector (23.2.5.3 [vector.data]).

    Citation Envoyé par JolyLoic Voir le message
    On va mettre ça sur le dos de l'heure tardive.
    Mettre quoi sur le dos de l'heure tardive?

    Citation Envoyé par JolyLoic Voir le message
    A tête un peu plus reposée, je dirais juste que c'est une notation pour indiquer que le fonction retourne une référence constante à un caractère nul.
    Notation pourrie.

    Citation Envoyé par JolyLoic Voir le message
    Ils ont un peu amélioré ça dans le brouillon du prochain standard, mais pour moi et pour beaucoup, l'erreur est d'avoir spécialisé vector<bool>, tout simplement :
    Effectivement : pour tout T, vector<T>::reference est une reference, donc vector<T>::operator[] renvoie une lvalue, sauf pour T = bool.

    De plus, dans la table des matières du brouillon de norme (N2315) :
    23.2.5 Class template vector
    23.2.6 Class vector<bool>
    ce n'est pas la même section!

Discussions similaires

  1. char * vers std::wstring
    Par chronos dans le forum SL & STL
    Réponses: 7
    Dernier message: 12/09/2007, 09h44
  2. [T-SQL]convert champ binaire en char
    Par arona dans le forum Sybase
    Réponses: 5
    Dernier message: 31/07/2006, 12h57
  3. std::cout et std::wstring
    Par glKabuto dans le forum SL & STL
    Réponses: 11
    Dernier message: 10/06/2006, 18h44
  4. (Problème avec...) conversion de std::string en char
    Par crossbowman dans le forum SL & STL
    Réponses: 7
    Dernier message: 05/03/2006, 19h54
  5. cannot convert 'std::string' to 'System::String ^'
    Par broadhead dans le forum MFC
    Réponses: 1
    Dernier message: 14/06/2005, 11h37

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