1
votes

Existe-t-il un équivalent de "for string in StringList do" dans C ++ Builder?

Je veux savoir s'il existe un équivalent pour Delphi

var 
   StringList: TStringList;
for str in StringList do 

dans C ++ Builder.


6 commentaires

Quelque chose comme std :: vector myStringList; for (auto str: myStringList) {...} . Difficile de répondre à moins que vous ne disiez ce que vous utilisez pour StringList


TStringList 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 :)


3 Réponses :


3
votes

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.


12 commentaires

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 ++, ...



4
votes

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.).

Mettre à jour

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;


4 commentaires

" 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.



3
votes

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


2 commentaires

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 au lieu d'utiliser C ++ 11.