Je veux savoir s'il existe un équivalent pour Delphi
var StringList: TStringList; for str in StringList do
dans C ++ Builder.
3 Réponses :
Le compilateur ou l'IDE n'ont pas beaucoup d'importance. Quel conteneur utilisez-vous pour vos std :: string
?
En général, par exemple, si vous utilisez std :: vector
avec std :: string
, vous pouvez écrire
std::vector<std::string> strings; // fill them for(auto& string : strings)
Cela fonctionne pour beaucoup d'autres conteneurs et classes.
edit: le texte original n'a rien révélé à propos de TStringList
, néanmoins, le code devrait être facilement transférable, si TStringList
propose des itérateurs.
Je ne connais pas Delphi, mais il vaut peut-être la peine de mentionner que cela fait une différence que vous écriviez auto &
ou const auto &
(ou simplement auto
)
Je pense que std::vector
devrait probablement être std::vector
?
OP utilise TStringList, qui est une classe de conteneur écrite en Delphi et également utilisée par C ++ Builder, qui contient des chaînes (AnsiString ou UnicodeString), pas des instances std :: string. Cela devrait répondre "quel conteneur utilisez-vous pour std :: string": rien Il utilise la TStringList de C ++ Builder, comme il l'a dit.
En d'autres termes: cette réponse semble agréable à ceux qui ne connaissent pas TStringList (d'où les votes positifs). C'est inutile pour ceux qui le font. Ce n’est pas une réponse , car elle est basée sur une prémisse complètement fausse. Ce n'est pas une question sur std :: vector , mais sur TStringList, et cela ne reçoit aucune réponse utile.
@RudyVelthuis oui, OP a changé le texte de sa question par la suite, il n'y avait aucun moyen de connaître TStringList
à ce moment-là
@IceFire: Je suis sûr que quiconque connaissant C ++ Builder aurait immédiatement su ce que cela signifiait. C'est pourquoi je pense qu'il est erroné d'utiliser la balise générale c ++ pour de telles questions, car elle est spécifique à C ++ Builder et n'a rien à voir avec le C ++ standard.
@RudyVelthuis Je suis d'accord, la balise c ++
est correctement supprimée maintenant
@Rigel Il existe certaines conventions après lesquelles vous écrivez des classes C ++. TStringList
, franchement, est mal écrit en termes de C ++ moderne. S'il offrait des itérateurs au begin
et end
de l'ensemble de chaînes, ma solution fonctionnerait en effet aussi pour TStringList
@IceFire - les classes vcl / rtl utilisées dans le générateur C ++ sont très différentes des classes C ++ "standard". Par exemple, ils agitent tous un ancêtre commun appelé TObject. Même les chaînes sont différentes (pas de # 0 à la fin de la chaîne). Je doute que le code C ++ "standard" puisse fonctionner sur eux. Si vous pensez le contraire, veuillez nous indiquer le code.
@ IceFire-TStringList est écrit en Pascal. Je ne sais pas exactement comment vous pouvez le comparer avec les conventions C ++.
@Rigel si vous pouvez l'utiliser en C ++, il y a probablement un équivalent C ++. Si tel est le cas, l'équivalent C ++ est écrit en C ++ et devrait être utilisable en conséquence, mais ce n'est qu'un jeu de devinettes de ma part
@IceFire Builder est une fusion entre C ++ et Object Pascal ... des parties de code sont en C ++ et des parties en Object Pascal ... Les parties Pascal sont généralement cachées des parties de code C ++ mais en raison de ce mécanisme les classes qui sont basées sur Pascal (VCL) ne sont pas les mêmes que les classes C ++, ...
Contrairement à ce que dit l'autre réponse, le compilateur compte beaucoup . Seul C ++ Builder peut utiliser des types dans la Bibliothèque de composants visuels , qui est écrite en Delphi (Object Pascal).
TStringList en est une. Il s'agit d'un conteneur (avec quelques extras) pour les instances System :: String (c'est-à-dire pas un conteneur std :: vector contenant des instances std :: string ).
TStringList n'expose pas les itérateurs C ++, donc AFAIK, actuellement, votre seul choix est l'indexation:
TStringList *list = new TStringList(); list->Add("Hello"); list->Add("World"); for (System::String str : list) { std::wcout << str.c_str() << std::endl; }
Vous pourrait bien sûr utiliser un std::vector<:string>
, mais cela ne vous donnerait pas la fonctionnalité supplémentaire d'une TStringList ( comme le stockage des objets associés - par exemple les bitmaps - ou la gestion spéciale des chaînes key = value , etc.).
Je dois ont fait quelque chose de mal. Comme l'a noté Rémy Lebeau, c'est en fait possible:
TStringList *list = new TStringList(); // fill list for (int i = 0; i < list->Count; ++i) { // ... } delete list;
" TStringList n'expose pas les itérateurs C ++ " - en fait, il le fait: Prise en charge de l'itérateur C ++ pour les types et conteneurs énumérables Delphi
@Remy: en effet, ça marche. Il semble que cela ne soit décrit que dans le docwiki pour les versions Tokyo et Rio.
il a en fait été introduit à Berlin
@Remy: Merci, mais évidemment aucune aide utilisable pour le moment.
Selon le DocWiki d'Embarcadero:
compilateurs basés sur CLang , vous pouvez faire des choses comme ceci:
TStringList *StringList = ...; for (auto str : StringList) { ... } std::for_each(std::begin(StringList), std::end(StringList), ...);
Cette fonctionnalité a été ajoutée dans C ++ Builder 10.1 Berlin.
Voir Utiliser les conteneurs Delphi de C ++ pour plus de détails
J'obtiens "[Erreur bcc32] E2141 Erreur de syntaxe de déclaration" sur la ligne "for (auto str: StringList)". Plus exactement, le compilateur place le curseur sur le point-virgule. J'ai C ++ 10.2 (Tokyo).
@Rigel ce message d'erreur indique que vous utilisez l'ancien BCC32 ("classique" NON-Clang), qui ne prend pas en charge C ++ 11. Vous devez utiliser l'un des compilateurs basés sur Clang a> au lieu d'utiliser C ++ 11.
Quelque chose comme
std :: vector myStringList; for (auto str: myStringList) {...}
. Difficile de répondre à moins que vous ne disiez ce que vous utilisez pour StringListTStringList est un type C ++ Builder et Delphi. Donc OP utilise TStringList , qui contient des instances System :: String, pas des instances std :: string.
FWIW, @IceFire a correctement supprimé la balise c ++ ici. Il s'agit d'une question spécifique à C ++ Builder et elle ne doit pas porter la balise c ++ (pour C ++ standard ).
la balise c ++ était présente car je pensais que C ++ pourrait avoir des fonctionnalités qui peuvent remplacer le Delphi "pour s dans la liste". Si je n'inclus pas de balise C ++, cela signifie que je ne réponds pas du monde C ++. Mais je veux ça. Quoi qu'il en soit, C ++ ne peut pas fonctionner sur un objet Delphi, c'est donc une question 100% Embarcadero-world :)
C ++ ne peut pas avoir de fonctionnalité pour un type spécifique de Delphi / C ++ Builder. La prochaine fois, de telles questions spécifiques devraient être sans la balise C ++ générale, car elle confond complètement les utilisateurs C ++ standard qui ne connaissent pas C ++ Builder. J'ai vu cela se produire plusieurs fois auparavant.
@RudyVelthuis - leçon apprise :)