2010-09-03 7 views
3

Comment ça se passe pour un titre accrocheur?Possibilité de convertir élégamment std: vector en cliext :: vector ou cli :: array <T>?

J'ai besoin de convertir en arrière d'un type compatible CLR, comme un tableau, et un type std :: vector.

Existe-t-il des méthodes d'adaptateur disponibles ou dois-je continuer à les copier à chaque fois que j'appelle l'une de mes méthodes natives?

Il existe quelques méthodes intéressantes de conversion entre les classes de variants STL cliext et les types CLR, mais je ne sais pas comment obtenir le vecteur standard dans les types STL sans une boucle next.

C'est ce que je fais un peu partout dans ce projet:

vector<double> galilVector = _galilClass->arrayUpload(marshal_as<string>(arrayName)); 
List<double>^ arrayList = gcnew List<double>(); 

// Copy out the vector into a list for export to .net 
for(vector<double>::size_type i = 0; i < galilVector.size(); i++) 
{ 
    arrayList->Add(galilVector[i]); 
} 

return arrayList->ToArray(); 

Répondre

4

Au lieu de « le faire partout », pourquoi ne pas vous faire cette logique en fonction réutilisable?

Quelque chose comme

template<typename T> 
generic<typename S> 
std::vector<T> marshal_as(System::Collections::Generic::ICollection<S>^ list) 
{ 
    if (list == nullptr) throw gcnew ArgumentNullException(L"list"); 
    std::vector<T> result; 
    result.reserve(list->Count); 
    for each (S& elem in list) 
    result.push_back(marshal_as<T>(elem)); 
    return result; 
} 

Rappelez-vous d'utiliser la fonction de membre de vecteur swap pour déplacer rapidement les éléments dans le vecteur que vous voulez les garder, si vous attribuez juste alors un constructeur de copie zillion seraient appelés.

+0

Merci. C'est une bonne solution réutilisable. –

+0

Pouvez-vous élaborer sur la référence d'échange ci-dessus? Je n'utilise pas beaucoup STL. –

+1

L'opérateur d'affectation et le constructeur de copie pour 'std :: vector' font tous deux une copie en profondeur. Donc 'std :: vector xyz = marshal_as (SomeCollectionOfSystemString);' convertira toute la chaîne .NET en chaînes C++ dans 'marshal_as', puis copiera toutes les chaînes du vecteur temporaire renvoyé par' marshal_as' dans xyz. Si à la place vous avez fait 'std :: vector xyz; xyz.swap (marshal_as (SomeCollectionOfSystemString)); 'alors le tableau de chaînes qui est le stockage de données interne du vecteur temporaire est transféré à' xyz' et aucune copie supplémentaire n'est faite. –

0
IList<int>^ Loader::Load(int id) 
{ 
    vector<int> items; 
    m_LoaderHandle->Loader->Load(id, items); 

    cliext::vector<int> ^result = gcnew cliext::vector<int>(items.size()); 
    cliext::copy(items.begin(), items.end(), result->begin()); 

    return result; 
} 
0

Vous pouvez essayer ceci:

cliext::vector<Single> vec_cliext; 
 
\t \t \t \t \t 
 
std::vector<float> vec_std; 
 

 
cliext::vector<Single>::iterator it = vec_cliext.begin(); 
 
for (; it != vec_cliext.end(); ++it) 
 
{ 
 
\t float temp = *it; 
 
\t vec_std.push_back(temp); 
 
}

Questions connexes