C++ std: noen eksempler

C Std Noen Eksempler



I C++-programmering introduserer 'std::any' fra Standard Template Library (STL) en dynamisk skriving for å håndtere heterogene data. I motsetning til tradisjonelle beholdere, tillater 'std::any' å lagre verdiene av enhver type i en enkelt beholder, noe som øker fleksibiliteten i scenarier der datatypene er ukjente eller varierer under kjøring. Denne typeagnostiske tilnærmingen fremmer en generisk programmering som gir utviklerne mulighet til å lage en mer tilpasningsdyktig og uttrykksfull kode samtidig som typesikkerheten opprettholdes. I denne utforskningen skal vi fordype oss i funksjonene til 'std::any', dets bruksmønstre og praktiske eksempler som illustrerer dens rolle i å skrive en robust og fleksibel C++-kode.

Eksempel 1: Grunnleggende bruk av Std::Any

Først, la oss utforske et enkelt eksempel for å demonstrere den grunnleggende bruken av 'std::any'. Tenk på et scenario der du trenger en funksjon for å godta ulike typer parametere:







Her er kodebiten:



#include
#inkluder

ugyldig prosessEventuell ( const std::any & verdi ) {
hvis ( verdi.har_verdi ( ) ) {
std::cout << 'Type lagret verdi: ' << verdi.type ( ) .Navn ( ) << std::endl;

hvis ( verdi.type ( ) == typeid ( int ) ) {
std::cout << 'Verdi: ' << std::any_cast < int > ( verdi ) << std::endl;
} ellers hvis ( verdi.type ( ) == typeid ( dobbelt ) ) {
std::cout << 'Verdi: ' << std::any_cast < dobbelt > ( verdi ) << std::endl;
} ellers hvis ( verdi.type ( ) == typeid ( std::streng ) ) {
std::cout << 'Verdi: ' << std::any_cast < std::streng > ( verdi ) << std::endl;
} ellers {
std::cout << 'Ustøttet type!' << std::endl;
}
} ellers {
std::cout << 'Ingen verdi lagret i std::any.' << std::endl;
}
}

int main ( ) {
behandle enhver ( 42 ) ;
behandle enhver ( 3.14 ) ;
behandle enhver ( std::streng ( 'Hei, std::any!' ) ) ;
behandle enhver ( 4,5f ) ; // Ustøttet type

komme tilbake 0 ;
}


I dette eksemplet definerer vi «processAny»-funksjonen som tar en «std::any»-referanse som en parameter og undersøker innholdet. Inne i funksjonen sjekker vi først om 'std::any'-variabelen har en lagret verdi ved å bruke has_value(). Hvis en verdi er tilstede, bestemmer vi typen til den lagrede verdien ved å bruke type().name() og fortsetter å skrive ut den tilsvarende verdien basert på typen. Hovedfunksjonen demonstrerer deretter nytten av 'processAny' ved å kalle den med forskjellige typer: et heltall (42), en dobbel (3.14) og en streng ('Hello, std::any!'). Funksjonen håndterer hver type riktig og skriver ut de respektive verdiene. Men når du forsøker å behandle et flyttallnummer (4.5f), som ikke støttes i dette eksemplet, håndterer programmet på en elegant måte situasjonen ved å indikere at typen ikke støttes.



Den genererte utgangen er:






Dette viser hvordan 'std::any' muliggjør dynamisk håndtering av ulike datatyper, noe som gjør det til et allsidig verktøy for generisk programmering i C++.

Eksempel 2: Lagring av brukerdefinerte typer

Det andre eksemplet utforsker hvordan denne dynamiske typen i Standard Template Library (STL) sømløst imøtekommer de tilpassede datastrukturene. Med fokus på en brukerdefinert type, punktstrukturen, viser vi hvordan 'std::any' håndterer forekomster av slike strukturer.



Her er koden:

#include
#inkluder

klasse MyClass {
offentlig:
Klassen min ( int verdi ) : data ( verdi ) { }

ugyldig utskriftsdata ( ) konst {
std::cout << 'Data i MyClass: ' << data << std::endl;
}

privat:
int data;
} ;

int main ( ) {
std::any anyObject = MyClass ( 42 ) ;

hvis ( anyObject.has_value ( ) ) {
auto & myClassInstance = std::any_cast < Klassen min &> ( anyObject ) ;
myClassInstance.printData ( ) ;
} ellers {
std::cout << 'Ingen verdi lagret i std::any.' << std::endl;
}

komme tilbake 0 ;
}


I denne C++-kodebiten lager vi et enkelt eksempel for å illustrere ved å bruke typen 'std::any' med en brukerdefinert klasse kalt 'MyClass'. Innenfor klassen er det en privat medlemsvariabel kalt 'data' og en offentlig metode kalt printData() for å vise verdien av disse dataene. En heltallsverdi sendes og tildeles 'data'-medlemmet i konstruktøren.

I 'hoved'-funksjonen instansierer vi et objekt av 'MyClass' med en startverdi på 42 og lagrer det deretter i 'std::any'-variabelen kalt 'anyObject'. Dette demonstrerer evnen til 'std::any' til å holde forekomstene av brukerdefinerte klasser.

Etter dette bruker vi en 'if'-setning for å sjekke om 'anyObject' har en verdi ved å bruke has_value()-metoden. Hvis det er en verdi, henter vi det lagrede objektet ved å bruke 'std::any_cast'. 'std::any_cast' brukes med malargumentet 'MyClass&' for å caste det lagrede objektet til en referanse til 'MyClass'. Denne referansen, 'myClassInstance', brukes deretter til å kalle printData()-metoden, og viser muligheten til å få tilgang til og operere på den lagrede brukerdefinerte typen i 'std::any'.

Hvis ingen verdi er lagret i 'std::any', skriver vi ut en melding som indikerer dette. Denne betingede kontrollen sikrer at vi håndterer scenariene der 'std::any'-variabelen kan være tom.

Her er utgangen:

Eksempel 3: Beholder av blandede typer

I programmering refererer en 'blandet type container' til en datastruktur som er i stand til å inneholde elementene til forskjellige, potensielt ikke-relaterte datatyper. Denne fleksibiliteten er verdifull når du arbeider med scenarier der datatypene er ukjente på kompileringstidspunktet eller endres dynamisk under programkjøring. I C++ eksemplifiserer 'std::any' dette konseptet, og tillater opprettelsen av en enkelt beholder for å lagre verdiene til forskjellige typer.

La oss utforske et scenario der vi lager en beholder som inneholder ulike typer:

#include
#inkluder
#inkluder

int main ( ) {

std::vektor < std::noen > blandetContainer;

mixedContainer.push_back ( 42 ) ;
mixedContainer.push_back ( 3.14 ) ;
mixedContainer.push_back ( std::streng ( 'Hallo' ) ) ;
mixedContainer.push_back ( ekte ) ;

til ( const auto & element: mixedContainer ) {
hvis ( element.type ( ) == typeid ( int ) ) {
std::cout << 'Heltall: ' << std::any_cast < int > ( element ) << std::endl;
} ellers hvis ( element.type ( ) == typeid ( dobbelt ) ) {
std::cout << 'Dobbelt: ' << std::any_cast < dobbelt > ( element ) << std::endl;
} ellers hvis ( element.type ( ) == typeid ( std::streng ) ) {
std::cout << 'String: ' << std::any_cast < std::streng > ( element ) << std::endl;
} ellers hvis ( element.type ( ) == typeid ( bool ) ) {
std::cout << 'Boolsk: ' << std::any_cast < bool > ( element ) << std::endl;
} ellers {
std::cout << 'Ukjent type' << std::endl;
}
}

komme tilbake 0 ;
}


I denne illustrasjonen demonstrerer vi konseptet med en blandet type container ved hjelp av C++ og 'std::any'-funksjonen. Vi oppretter 'std::vector' kalt 'mixedContainer' for å fungere som vår beholder for å holde elementene i forskjellige datatyper. Ved å bruke 'push_back'-funksjonen fyller vi denne beholderen med forskjellige elementer, inkludert et heltall (42), en dobbel (3.14), en streng ('Hello') og en boolsk (true).

Når vi itererer gjennom 'mixedContainer' ved å bruke en 'for'-løkke, bruker vi type()-funksjonen for å identifisere hvert elements datatype dynamisk. Ved å bruke 'std::any_cast', trekker vi ut og skriver ut de tilsvarende verdiene basert på typene deres. For eksempel, hvis elementet er av typen 'int', skriver vi det ut som et heltall. Hvis den er av typen 'dobbel', skriver vi den ut som en dobbel, og så videre.

Her er den genererte utgangen:

Eksempel 4: Feilhåndtering med Std::Any

Håndtering av feil ved bruk av 'std::any' innebærer å sjekke om typen støttes eller om en verdi er lagret. I dette eksemplet viser vi hvordan du håndterer typene som ikke støttes:

#include
#inkluder

int main ( ) {
std::any myAny = 42 ;

prøve {

dobbel verdi = std::any_cast < dobbelt > ( myAny ) ;
std::cout << 'Verdi: ' << verdi << std::endl;
} å fange ( const std::bad_any_cast & Det er ) {

std::cerr << 'Feil: ' << e.hva ( ) << std::endl;
}

komme tilbake 0 ;
}


Vi starter med å initialisere 'std::any'-variabelen, 'myAny', med verdien 42 av heltallstypen. Inne i den påfølgende 'try'-blokken gjør vi et eksplisitt forsøk på å kaste denne heltallsverdien inn i en 'double' ved å bruke 'std::any_cast'-operasjonen. Men siden den faktiske typen som er lagret i 'myAny' er et heltall, er denne casting-operasjonen ugyldig for en 'double' som fører til en mismatch type.

For å håndtere denne potensielle feilen elegant implementerer vi unntakshåndteringen med en 'catch'-blokk som er designet for å fange opp den spesifikke unntakstypen 'std::bad_any_cast'. I tilfelle en mislykket cast aktiveres 'catch'-blokken og vi genererer en feilmelding ved å bruke 'std::cerr' for å kommunisere arten av feilen. Denne feilhåndteringsstrategien sikrer at programmet vårt på en elegant måte kan håndtere situasjonene der den forsøkte typen cast kolliderer med den faktiske typen som er lagret i variabelen 'std::any'.

Konklusjon

I denne artikkelen utforsket vi applikasjonene til 'std::any' i C++, en dynamisk typebeholder som er introdusert i C++ for verdier av forskjellige typer. Vi demonstrerte dens allsidighet gjennom forskjellige eksempler, og viste scenarier som spenner fra grunnleggende bruk til håndtering av brukerdefinerte typer og heterogene samlinger. Vi demonstrerte dens praktiske anvendelse i scenarier der typen data ikke er kjent på kompileringstidspunktet. I tillegg utforsket vi om feilhåndteringsteknikker, og understreket viktigheten av å elegant administrere de ikke-støttede typene gjennom unntakshåndtering.