C++ std:alle voorbeelden

C Std Alle Voorbeelden



Bij programmeren in C++ introduceert “std::any” uit de Standard Template Library (STL) een dynamische typering om heterogene gegevens te verwerken. In tegenstelling tot traditionele containers maakt “std::any” het mogelijk om de waarden van elk type binnen één enkele container op te slaan, waardoor de flexibiliteit wordt vergroot in scenario’s waarin de gegevenstypen onbekend zijn of variëren tijdens runtime. Deze type-agnostische benadering bevordert een generieke programmering die de ontwikkelaars in staat stelt een meer aanpasbare en expressieve code te creëren met behoud van de typeveiligheid. In deze verkenning zullen we dieper ingaan op de kenmerken van “std::any”, de gebruikspatronen ervan en praktische voorbeelden die de rol ervan illustreren bij het schrijven van een robuuste en flexibele C++-code.

Voorbeeld 1: Basisgebruik van Std::Any

Laten we eerst een eenvoudig voorbeeld verkennen om het fundamentele gebruik van “std::any” te demonstreren. Overweeg een scenario waarin u een functie nodig heeft om verschillende soorten parameters te accepteren:







Hier is het codefragment:



#include
#include

ongeldig procesAny ( const std::elke & waarde ) {
als ( waarde.heeft_waarde ( ) ) {
std::uit << 'Type opgeslagen waarde: ' << waarde type ( ) .naam ( ) << std::endl;

als ( waarde type ( ) == typenummer ( int ) ) {
std::uit << 'Waarde: ' << std::any_cast < int > ( waarde ) << std::endl;
} anders als ( waarde type ( ) == typenummer ( dubbele ) ) {
std::uit << 'Waarde: ' << std::any_cast < dubbele > ( waarde ) << std::endl;
} anders als ( waarde type ( ) == typenummer ( std::tekenreeks ) ) {
std::uit << 'Waarde: ' << std::any_cast < std::tekenreeks > ( waarde ) << std::endl;
} anders {
std::uit << 'Niet-ondersteund type!' << std::endl;
}
} anders {
std::uit << 'Geen waarde opgeslagen in std::any.' << std::endl;
}
}

int. hoofd ( ) {
procesElk ( 42 ) ;
procesElk ( 3.14 ) ;
procesElk ( std::tekenreeks ( 'Hallo, std::any!' ) ) ;
procesElk ( 4,5 f ) ; // Niet ondersteund type

opbrengst 0 ;
}


In dit voorbeeld definiëren we de functie “processAny” die een referentie “std::any” als parameter gebruikt en de inhoud ervan onderzoekt. Binnen de functie controleren we eerst of de “std::any” variabele een opgeslagen waarde heeft met behulp van has_value(). Als er een waarde aanwezig is, bepalen we het type van de opgeslagen waarde met behulp van type().name() en gaan we verder met het afdrukken van de overeenkomstige waarde op basis van het type. De hoofdfunctie demonstreert vervolgens het nut van “processAny” door het met verschillende typen aan te roepen: een geheel getal (42), een double (3.14) en een string (“Hallo, std::any!”). De functie verwerkt elk type op de juiste manier en drukt de respectieve waarden af. Wanneer echter wordt geprobeerd een getal met drijvende komma (4.5f) te verwerken, dat in dit voorbeeld niet wordt ondersteund, handelt het programma de situatie netjes af door aan te geven dat het type niet wordt ondersteund.



De gegenereerde uitvoer is:






Dit laat zien hoe “std::any” de dynamische verwerking van verschillende gegevenstypen mogelijk maakt, waardoor het een veelzijdig hulpmiddel wordt voor generiek programmeren in C++.

Voorbeeld 2: De door de gebruiker gedefinieerde typen opslaan

Het tweede voorbeeld onderzoekt hoe dit dynamische type binnen de Standard Template Library (STL) naadloos de aangepaste datastructuren huisvest. Door ons te concentreren op een door de gebruiker gedefinieerd type, de puntstructuur, laten we zien hoe “std::any” omgaat met de instanties van dergelijke structuren.



Hier is de code:

#include
#include

klasse MijnKlasse {
openbaar:
Mijn klas ( int-waarde ) : gegevens ( waarde ) { }

ongeldige printData ( ) const {
std::uit << 'Gegevens in MijnKlasse: ' << gegevens << std::endl;
}

privaat:
int-gegevens;
} ;

int. hoofd ( ) {
std::any anyObject = MijnKlasse ( 42 ) ;

als ( anyObject.heeft_waarde ( ) ) {
auto & myClassInstance = std::any_cast < Mijn klas &> ( elkObject ) ;
mijnClassInstance.printData ( ) ;
} anders {
std::uit << 'Geen waarde opgeslagen in std::any.' << std::endl;
}

opbrengst 0 ;
}


In dit C++-codefragment maken we een eenvoudig voorbeeld om het gebruik van het type “std::any” te illustreren met een door de gebruiker gedefinieerde klasse genaamd “MyClass”. Binnen de klasse is er een private lidvariabele genaamd “data” en een publieke methode genaamd printData() om de waarde van deze gegevens weer te geven. Er wordt een geheel getalwaarde doorgegeven en toegewezen aan het “data” -lid in de constructor.

In de functie “main” instantiëren we een object van “MyClass” met een initiële waarde van 42 en slaan het vervolgens op in de variabele “std::any” met de naam “anyObject”. Dit demonstreert de mogelijkheid van “std::any” om de instanties van door de gebruiker gedefinieerde klassen vast te houden.

Hierna gebruiken we een “if”-instructie om te controleren of “anyObject” een waarde heeft met behulp van de has_value() methode. Als er een waarde is, halen we het opgeslagen object op met behulp van “std::any_cast”. De “std::any_cast” wordt gebruikt met het “MyClass&” sjabloonargument om het opgeslagen object naar een referentie van “MyClass” te casten. Deze referentie, “myClassInstance”, wordt vervolgens gebruikt om de methode printData() aan te roepen, waarmee de mogelijkheid wordt getoond om toegang te krijgen tot en te werken met het opgeslagen, door de gebruiker gedefinieerde type binnen de “std::any”.

Als er geen waarde is opgeslagen in “std::any”, printen we een bericht waarin dit wordt aangegeven. Deze voorwaardelijke controle zorgt ervoor dat we de scenario's afhandelen waarin de variabele “std::any” mogelijk leeg is.

Hier is de uitvoer:

Voorbeeld 3: Container met gemengde typen

Bij programmeren verwijst een ‘mixed-type container’ naar een datastructuur die in staat is de elementen van diverse, potentieel niet-gerelateerde datatypen te bevatten. Deze flexibiliteit is waardevol bij het omgaan met scenario's waarbij de gegevenstypen tijdens het compileren onbekend zijn of dynamisch veranderen tijdens de uitvoering van het programma. In C++ is “std::any” een voorbeeld van dit concept, waardoor een enkele container kan worden gemaakt om de waarden van verschillende typen op te slaan.

Laten we een scenario onderzoeken waarin we een container maken die verschillende typen bevat:

#include
#include
#include

int. hoofd ( ) {

std::vector < standaard::elke > gemengdContainer;

gemengdeContainer.push_back ( 42 ) ;
gemengdeContainer.push_back ( 3.14 ) ;
gemengdeContainer.push_back ( std::tekenreeks ( 'Hallo' ) ) ;
gemengdeContainer.push_back ( WAAR ) ;

voor ( const auto & element: gemengdeContainer ) {
als ( element.type ( ) == typenummer ( int ) ) {
std::uit << 'Geheel getal: ' << std::any_cast < int > ( element ) << std::endl;
} anders als ( element.type ( ) == typenummer ( dubbele ) ) {
std::uit << 'Dubbel:' << std::any_cast < dubbele > ( element ) << std::endl;
} anders als ( element.type ( ) == typenummer ( std::tekenreeks ) ) {
std::uit << 'Snaar: ' << std::any_cast < std::tekenreeks > ( element ) << std::endl;
} anders als ( element.type ( ) == typenummer ( bool ) ) {
std::uit << 'Booleaans: ' << std::any_cast < bool > ( element ) << std::endl;
} anders {
std::uit << 'Onbekend type' << std::endl;
}
}

opbrengst 0 ;
}


In deze illustratie demonstreren we het concept van een container van gemengd type met behulp van C++ en de functie “std::any”. We creëren de “std::vector” met de naam “mixedContainer” om te dienen als onze container voor de elementen van verschillende gegevenstypen. Met behulp van de functie “push_back” vullen we deze container met verschillende elementen, waaronder een geheel getal (42), een double (3.14), een string (“Hallo”) en een Booleaanse waarde (true).

Terwijl we de “mixedContainer” doorlopen met behulp van een “for”-lus, gebruiken we de functie type() om het gegevenstype van elk element dynamisch te identificeren. Met behulp van “std::any_cast” extraheren en printen we de overeenkomstige waarden op basis van hun typen. Als het element bijvoorbeeld van het type “int” is, drukken we het af als een geheel getal. Als het van het type ‘dubbel’ is, drukken we het af als een dubbele, enzovoort.

Hier is de gegenereerde uitvoer:

Voorbeeld 4: Foutafhandeling met Std::Any

Bij het afhandelen van fouten bij het gebruik van “std::any” wordt gecontroleerd of het type wordt ondersteund en of er een waarde is opgeslagen. In dit voorbeeld laten we zien hoe u omgaat met de niet-ondersteunde typen:

#include
#include

int. hoofd ( ) {
std::any myAny = 42 ;

poging {

dubbele waarde = std::any_cast < dubbele > ( mijnAny ) ;
std::uit << 'Waarde: ' << waarde << std::endl;
} vangst ( const std::bad_any_cast & Het is ) {

std::cerr << 'Fout: ' << e.wat ( ) << std::endl;
}

opbrengst 0 ;
}


We beginnen met het initialiseren van de “std::any” variabele, “myAny”, met de waarde 42 van het integer-type. Binnen het volgende “try”-blok doen we een expliciete poging om deze gehele waarde in een “double” te gieten met behulp van de “std::any_cast”-bewerking. Omdat het daadwerkelijke type dat is opgeslagen in “myAny” echter een geheel getal is, is deze castingbewerking ongeldig voor een “double”, wat leidt tot een niet-overeenkomend type.

Om deze potentiële fout netjes te beheren, implementeren we de afhandeling van uitzonderingen met een “catch” -blok dat is ontworpen om het specifieke uitzonderingstype “std::bad_any_cast” op te vangen. In het geval van een mislukte cast wordt het ‘catch’-blok geactiveerd en genereren we een foutmelding met behulp van ‘std::cerr’ om de aard van de fout te communiceren. Deze strategie voor foutafhandeling zorgt ervoor dat ons programma probleemloos kan omgaan met situaties waarin de poging tot typecast botst met het daadwerkelijke type dat is opgeslagen in de variabele 'std::any'.

Conclusie

In dit artikel hebben we de toepassingen van “std::any” in C++ onderzocht, een container van het dynamische type die in C++ is geïntroduceerd voor waarden van verschillende typen. We hebben de veelzijdigheid ervan aangetoond aan de hand van verschillende voorbeelden, waarbij scenario's worden getoond die variëren van basisgebruik tot het omgaan met door de gebruiker gedefinieerde typen en heterogene collecties. We hebben de praktische toepassing ervan gedemonstreerd in scenario's waarin het type gegevens tijdens het compileren niet bekend is. Daarnaast hebben we de technieken voor foutafhandeling onderzocht, waarbij we het belang benadrukten van een correct beheer van de niet-ondersteunde typen door middel van uitzonderingsafhandeling.