La conversion de std::list pour C amicale type
Ce qui est la façon la plus élégante pour retourner un std::list
objet à partir d'un partage lib fonction (mis en œuvre par le code C++) pour un C consommateur? Je sais que pour std::vector
, nous pouvons retourner à l'adresse du 1er élément du vecteur et ont les consommateurs de la traiter comme un tableau, mais std::list est mis en œuvre comme un lis.
- Le standard C++ garantir qu'un
std::vector
objet du premier élément est le premier élément d'une matrice, et peuvent être traités en tant que tels? - Oui............
- malgré la croyance populaire, de la 1998 la norme C++ ne pas garantie que
std::vector
est contiguë. Toutefois, la Norme n'certainement dire et (à un certain degré) supposons que c'est le cas. Ce problème est résolu en C++03. Voir (stackoverflow.com/questions/247738/...) et (herbsutter.wordpress.com/2008/04/07/...) pour plus de détails. - merci!
Vous devez vous connecter pour publier un commentaire.
Copiez le
std::list
à unstd::vector
et le retourner à l'adresse du premier élément, comme vous l'avez déjà mentionné.(Bien sûr, cela peut signifier que vous ne voulez pas être l'aide d'un
std::list
en premier lieu.)(Cette solution suppose que l'objet en cours d'accès est appartenant par la bibliothèque C++ -- Si ce n'est pas le cas, vous pouvez avoir besoin d'envisager d'allouer de la mémoire à partir de votre code en C et en passant un pointeur dans la bibliothèque C++ pour copier les données.)
vous pouvez toujours faire une copie:
new
, alors vous avez de risques, l'appelant dispose de l'aide defree
qui conduit à un comportement indéfiniSi vous voulez le code client de manipuler une liste, vous devrez définir un C type:
et retourne un pointeur sur la tête de la liste:
Ce qui signifie que vous devrez copier le contenu de votre
std::list
pour un C comme structure de données de liste si vous voulez le code client de manipuler une liste.Sinon, vous pouvez copier le contenu de votre
std::list
dans un bloc de mémoire contiguë, de retour de ce bloc à l'appelant, mais dans ce cas c'est l'appelant responsabilité de libérer de la mémoire. Renvoyer un tableau signifie aussi la mémoire de nettoyage doit être fait avec une fonction compatible avec la fonction que vous avez utilisé pour allouer le bloc: votre mise en œuvre sera probablement utilisermalloc
et pasnew
d'allouer un bloc, de sorte que l'appelant peut ensuite utiliserfree
sur le bloc.Essayer quelque chose comme cela, pas besoin d'un
std::copy
si vous ne voulez pas l'utiliser:La seule façon de le faire est de retourner à un void* à la obejct.
Ensuite fournir un ensemble de fonctions qui acceptent le void* et de manipuler la liste dans le code C++.
Edit:
Pour ceux qui vont Hein.
std::list
std::list
est un détail de l'implémentation interne de la bibliothèque C++, d'où l'enveloppant l'ensemble de la liste de l'API n'est ni élégant, ni un sage choix de conception.Vous pouvez obtenir un itérateur ou de la liste et de remplir un vecteur avec elle:
Et ensuite vous pouvez travailler avec elle comme avec le vecteur que vous êtes familier avec.
std::vector<node> nodeVector(nodes.begin(), nodes.end());