La sortie du code suivant me confond:
> S1: Mod > S2: ern C++
sortie:
const std::string str = "Modern C++"; std::string s1 {"Modern C++", 3}; std::string s2 {str, 3}; std::cout << "S1: " << s1 << "\n"; std::cout << "S2: " << s2 << "\n";
Quelqu'un peut-il expliquer ce résultat?
4 Réponses :
De:
https://en.cppreference.com/w / cpp / string / basic_string / basic_string
basic_string( const basic_string& other, size_type pos, const Allocator& alloc = Allocator() );
utilise le constructeur suivant:
std::string s2 {str, 3};
prend donc 3 Chars à obtenir mod
.
basic_string( const CharT* s, size_type count, const Allocator& alloc = Allocator() );
utilisera le constructeur suivant:
std::string s1 {"Modern C++", 3};
Ainsi, la prise La chaîne de la position 3 donnant: ERN C ++
.
Merci. Le premier est size_type count
et le second est size_type pos
.
Il faut demander pourquoi ils ajouteraient jamais deux constructeurs avec un comportement aussi différent. C'est comme s'il était pavé avec aucune pensée du tout.
@PolyGnome: "Coblé sans aucune pensée" décrit essentiellement l'ensemble de std :: string
. Il tient également compte du mélange de méthodes basées sur l'indice et basées sur les itérateurs - String a été développé indépendamment du STL, puis rétroactivement augmenté pour correspondre - et en général a trop de "méthodes de commodité. J'aime toujours gotw # 84: monoliths unsetrung qui plonge dans une API de chaîne minimale complétée par des fonctions libres.
Y a-t-il même un cas d'utilisation pour ce constructeur de sous-chaîne qui ne serait pas servi par la méthode substr
?
L'un appelle string (char const *, count)
, l'autre chaîne (chaîne const &, pos)
.
L'un obtient les 3 premiers caractères d'un tampon, l'autre tous les personnages après le 3.
En effet, C ++ a des tampons de caractères bruts et des chaînes STD. "Ce n'est pas une chaîne std :: string"
. "Ceci est une chaîne std" s
, std :: string so_is = "this";
.
std :: string
a plus de 30 ans, et il a été ajouté à la langue C ++ sans soin suffisant (contrairement au STL, qui a subi plus d'itérations avant d'être ajoutée). P >
Son interface est honnêtement trop riche, et vous pouvez rencontrer des trucs comme celui-ci; Plusieurs surcharges qui conduisent à des résultats déroutants.
quelqu'un peut m'expliquer pourquoi est-ce?
Cela est dû à std :: string
ayant des constructeurs qui ne devraient vraiment pas (@orr expliquée Les détails). Et il ne devrait pas avoir ces constructeurs parce que:
Ce n'est pas le seul cas de la bibliothèque standard avec de tels constructeurs sous-deux (IMHO); std :: vector
est (in) célèbre Pour trop de variété de constructeurs et déroutant / sementiers de constructeurs déroutants. p>
Leçons de vie:
au cas où vous souhaitez obtenir la même sortie que
mod pour S1
mod pour S2
vous Peut utiliser un pointeur charbon pour Str, par exemple
Mod Mod
La sortie
char * str = "Modern C++"; std::string s1 {"Modern C++", 3}; std::string s2 {str, 3}; std::cout << "S1: " << s1 << "\n"; std::cout << "S2: " << s2 << "\n";
Pour que cela fonctionne, la première ligne doit être: char str [] = "C ++ moderne"; ou char str [] {"C ++ moderne"};
Essayez-le, pour moi, cela a très bien fonctionné. En C ++ / C, vous pouvez également déclarer et initialiser un tableau de caractères avec un pointeur. char * str = "C ++ moderne"; Utilisez STR [Valeur] pour faire passer car STR est maintenant un tableau.
Je crois que la syntaxe sans [] est char ** str.
char * str = "C ++ moderne";
est, ironiquement, un C ++ moderne non valide. const est requis à C ++ 11. wandbox.org/permlink/e3ta4tkbrkbooull (gcc) / wandbox.org/permlink/tftryb565svyhmlb (clang)
S1 et S2 devraient être les mêmes à moins que je manque quelque chose.
Avez-vous lu la référence sur
std :: string < / code> constructeurs?
"C ++ moderne"
n'est pas unstd :: string
mais un tableau de caractères (qui est automatiquement converti en pointeur de char), et il y a un constructeur différent pour ceux-ci.Bien sûr. La référence vous le dirait. Et je suis sûr qu'il y a une raison incroyablement intelligente qui ne fait pas la même chose, ce que le comité de bibliothèque C ++ me prouverait en utilisant une logique et un raisonnement impeccables. Et pourtant, ce n'est qu'une raison de plus - bien que petite - que la bibliothèque standard C ++ reste inutile, voire frustrante, à utiliser.
@Holyblackcat Néanmoins, le résultat devrait être le même, merci quand même.
Oui, ça devrait probablement.
La "raison incroyablement intelligente" est que Std :: String a été initialement conçu il y a des décennies, donc avec le recul, certains de ses constructeurs et fonctions ne correspondent pas à ce que nous considérerions comme une interface intuitive moderne
@ M.M.: Cela, en plus du fait que les chaînes de style C ont été conçues il y a encore plus longtemps, et
std :: string
a dû travailler avec leurs conventions. Cela dit, aurait probablement dû rester avec la même sémantique de chaîne de style C pour les deux, au lieu d'avoir une position être un point de départ efficace pourstd :: string
, et un point final efficace pourchar *
, donc votre point se dresse toujours, en soulignant simplement que les contraintes de compatibilité dans ce royaume sont antérieures àstd :: string
.C'est vraiment un exemple magnifiquement parfait de la raison pour laquelle certains pourraient prétendre que C ++ "suce".
@ M.M La cohérence et la logique ne sont guère des inventions récentes
TBH, je pense que le vrai problème est que chaque classe a un nom de constructeur - le nom de classe. Vous ne pouvez pas avoir différents constructeurs pour la même classe avec des noms différents, et ne pouvez avoir que plusieurs constructeurs en raison de la surcharge. Différentes surcharges avec le même nom faisant des choses différentes est malodorante, mais c'est ce que nous sommes coincés pour les constructeurs. Sauf que ce que vous devriez probablement faire, c'est se déplacer-construction d'une fonction nommée qui renvoie la valeur que vous voulez - n'utilisez pas du tout tous les constructeurs déroutants, ce sont des reliques obsolètes imo depuis un âge avant de déplacer la sémantique.