IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

[Aller plus loin] C++ - Extraire des collections de données depuis une collection initiale
Un billet blog de Bousk

Le , par Bousk

0PARTAGES

Dans le billet précédent, nous avons vu comment extraire des collections de données depuis un vector sans aucune allocation supplémentaire.
La conclusion laissait entendre que ce système est applicable à d'autres collections que std::vector.

Ça l'est, et relativement simplement.

Pour y parvenir, il suffit d'ajouter un niveau de template, en modifiant le template pour pas être le type de l'élément mais de la collection.
Ainsi, VectorView devient donc ContainerView:
template
class ContainerView
{
public:
using Type = Container;
using Element = typename Type::value_type;
using Iterator = typename Type::iterator;
using ConstIterator = typename Type::const_iterator;
public:
ContainerView()
{
// Default values to prevent iterating over random memory
m_begin = m_end;
}
ContainerView(typename ConstIterator first, typename ConstIterator end)
: m_begin(first)
, m_end(end)
{}
ConstIterator begin() const { return m_begin; }
ConstIterator end() const { return m_end; }
private:
typename ConstIterator m_begin, m_end;
};
Et nous pouvons créer des allias pour continuer à utiliser VectorView aisément:

template
using VectorView = ContainerView>;
template
using ListView = ContainerView>;

Il faut propager le changement aux fonctions.
Les plus attentifs auront remarqué que des allias sur le container interne, ses itérateurs et le type interne ont été ajouté à ContainerView. La syntaxe correspond aux types de std, mais peut être adaptée à vos propres collections.
Ceci permet de simplifier son utilisation, en passant un unique paramètre template qui sera la vue:

template
typename View::Iterator CreateLists(typename View::Iterator first, typename View::Iterator end, View& list)
{
list = View(first, end);
return end;
}
template
typename View::Iterator CreateLists(typename View::Iterator first, typename View::Iterator end, View& list, const std::function& extracter)
{
auto firstNonExtracted = std::stable_partition(first, end, extracter);
list = View(first, firstNonExtracted);
return firstNonExtracted;
}
template
void CreateLists(typename View::Iterator first, typename View::Iterator end, View& list, const std::function& extracter, Args&&... args)
{
auto newFirst = CreateLists(first, end, list, extracter);
CreateLists(newFirst, end, std::forward(args)...);
}
Enfin, petite mise à jour similaire pour notre petite fonction d'affichage de collection:
template
void PrintValues(const char* name, View values)
{
std::cout << name << " : ";
for (auto&& value : values)
std::cout << value << ", ";
std::cout << std::endl;
}

L'utilisation est identique, voire simplifiée : le paramètre template à l'appel de CreateLists, que VS2019 ne semblait pas pouvoir déduire et était obligatoire dans le premier billet, ne l'est plus !
int main()
{
{
std::vector values;
for (int i = 0; i < 100; ++i)
values.push_back(i);

VectorView pairs;
VectorView mul3;
VectorView mul5;
VectorView mul7;
VectorView others;

CreateLists(values.begin(), values.end()
, pairs, [](int v) { return v % 2 == 0; }
, mul3, [](int v) { return v % 3 == 0; }
, mul5, [](int v) { return v % 5 == 0; }
, mul7, [](int v) { return v % 7 == 0; }
, others
);

PRINT_VALUES_WITH_NAME(pairs);
PRINT_VALUES_WITH_NAME(mul3);
PRINT_VALUES_WITH_NAME(mul5);
PRINT_VALUES_WITH_NAME(mul7);
PRINT_VALUES_WITH_NAME(others);
}
{
std::list values;
for (int i = 0; i < 100; ++i)
values.push_back(i);

ListView pairs;
ListView mul3;
ListView mul5;
ListView mul7;
ListView others;

CreateLists(values.begin(), values.end()
, pairs, [](int v) { return v % 2 == 0; }
, mul3, [](int v) { return v % 3 == 0; }
, mul5, [](int v) { return v % 5 == 0; }
, mul7, [](int v) { return v % 7 == 0; }
, others
);

PRINT_VALUES_WITH_NAME(pairs);
PRINT_VALUES_WITH_NAME(mul3);
PRINT_VALUES_WITH_NAME(mul5);
PRINT_VALUES_WITH_NAME(mul7);
PRINT_VALUES_WITH_NAME(others);
}

return 0;
}

Vous avez lu gratuitement 3 540 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !