Nëse në fillim të shfaqjes thoni se në mur ka një kod në C++, atëherë deri në fund ai patjetër do t'ju godasë në këmbë.
Bjarne Stroustrup
Nga 31 tetori deri mĂ« 1 nĂ«ntor, nĂ« ShĂ«n Petersburg u zhvillua konferenca C++ Russia Piter â njĂ« nga konferencat mĂ« tĂ« mĂ«dha pĂ«r programim nĂ« Rusi, e organizuar nga JUG Ru Group. NdĂ«r folĂ«sit e ftuar ishin anĂ«tarĂ« tĂ« komitetit pĂ«r standardizimin e C++, folĂ«s nga CppCon, autorĂ« libresh nga shtĂ«pia botuese OâReilly, si dhe mbajtĂ«s tĂ« projekteve si LLVM, libc++ dhe Boost. Konferenca Ă«shtĂ« e orientuar pĂ«r zhvilluesit e pĂ«rvojshĂ«m nĂ« C++, tĂ« cilĂ«t dĂ«shirojnĂ« tĂ« thellojnĂ« ekspertizĂ«n e tyre dhe tĂ« ndajnĂ« pĂ«rvojĂ«n nĂ« komunikim tĂ« drejtpĂ«rdrejtĂ«. StudentĂ«t, doktorantĂ«t dhe mĂ«suesit e universiteteve pĂ«rfitojnĂ« nga ulje shumĂ« tĂ« kĂ«ndshme.
Botimi i MoskĂ«s i konferencĂ«s do tĂ« mbahet nĂ« prill tĂ« vitit tĂ« ardhshĂ«m, ndĂ«rsa pĂ«r momentin studentĂ«t tanĂ« do tĂ« tregojnĂ« se çfarĂ« interesante mĂ«suan nĂ« kĂ«tĂ« ngjarje.Â

Foto nga
Rreth nesh
PĂ«r kĂ«tĂ« postim punuan dy studentĂ« tĂ« NIU HSE â ShĂ«n Petersburg:
- Liza Vasiljenko â student i vitit tĂ« katĂ«rt nĂ« programin e bachelor-it, duke studiuar fushĂ«n "Gjuhtet e Programimit" nĂ« programin "Matematika e Aplikuar dhe Informatika". Duke u njohur me gjuhĂ«n C++ nĂ« vitin e parĂ« tĂ« universitetit, mĂ« pas fitoi pĂ«rvojĂ« pune me tĂ« nĂ« praktika nĂ« industri. Pasioni pĂ«r gjuhĂ«t e programimit nĂ« pĂ«rgjithĂ«si dhe programimin funksional nĂ« veçanti ndikoi nĂ« pĂ«rzgjedhjen e temave pĂ«r konferencĂ«.
- Danya Smirnov â student i vitit tĂ« parĂ« nĂ« programin e magjistraturĂ«s "Programimi dhe Analiza e tĂ« DhĂ«nave". QĂ« nĂ« shkollĂ« shkruante probleme olimpike nĂ« C++, dhe mĂ« pas ndodhi qĂ« gjuha gjithmonĂ« shfaqej nĂ« aktivitetet e tij akademike dhe pĂ«rfundimisht u bĂ« gjuha kryesore e punĂ«s. Vendosi tĂ« marrĂ« pjesĂ« nĂ« konferencĂ« pĂ«r tĂ« rritur njohuritĂ« e tij, si dhe pĂ«r tĂ« mĂ«suar mbi mundĂ«sitĂ« e reja.
Në gazetën e fakultetit shpesh ndahen informacione mbi ngjarje edukative që lidhen me disiplinën tonë. Në shtator pamë informacion mbi C++ Russia dhe vendosëm të regjistroheshim si dëgjues. Ky është eksperienca jonë e parë në pjesëmarrjen në këtë lloj konferencash.
Struktura e konferencës
Referatet
Në dy ditë, ekspertët mbajtën 30 ligjërata, duke trajtuar shumë tema aktuale: aplikime të zgjuara të karakteristikave të gjuhës për zgjidhjen e detyrave praktike, azhurnimet e ardhshme të gjuhës në lidhje me standardin e ri, kompromiset gjatë dizajnimit të C++ dhe masat për kujdes gjatë punës me pasojat e tyre, shembuj të arkitekturës interesante të projekteve, si dhe disa detaje nën kapuçin e infrastrukturës së gjuhës. Në të njëjtën kohë zhvilloheshin 3 ligjërata, më shpesh dy në rusisht dhe një në anglisht.
Zonat e diskutimit
Pas ligjëratave, të gjitha pyetjet e pa bërë dhe diskutimet e papërfunduaraTransferoheshin në zona të veçanta të komunikimit me folësit, të pajisura me tabela shënuesish. Një mënyrë e mirë për të kaluar një pushim midis ligjëratave me një bisedë të këndshme.
Ligjëratat e shpejta dhe diskutimet informale
NĂ«se dĂ«shiron tĂ« mbash njĂ« ligjĂ«ratĂ« tĂ« shkurtĂ«r â mund tĂ« regjistrohesh nĂ« tabelĂ«n e shĂ«nuesve pĂ«r LigjĂ«ratĂ«n e ShpejtĂ« tĂ« mbrĂ«mjes dhe tĂ« marrĂ«sh pesĂ« minuta pĂ«r tĂ« folur pĂ«r çfarĂ«do gjĂ«je nĂ« lidhje me temĂ«n e konferencĂ«s. PĂ«r shembull, njĂ« prezantim i shpejtĂ« mbi sanitizers pĂ«r C++ (pĂ«r disa ishte njĂ« risi) ose njĂ« histori pĂ«r njĂ« bug nĂ« gjenerimin e sinusoidĂ«s, qĂ« mund tĂ« dĂ«gjohet, por jo tĂ« shikohet.
Format tjetĂ«r â diskutimi nĂ« panel "Me komitetin pĂ«r shpirtin". NĂ« skenĂ« â disa anĂ«tarĂ« tĂ« komitetit pĂ«r standardizimin, nĂ« projektorin â njĂ« zjarri (zyrtarisht â pĂ«r tĂ« krijuar njĂ« atmosferĂ« tĂ« ngrohtĂ«, por arsyeja "sepse TĂ GJITHA JANĂ NĂ ZJAR" duket mĂ« qesharake), pyetjet â mbi standardin dhe vizionin e pĂ«rgjithshĂ«m pĂ«r C++, pa diskutime teknike tĂ« ashpra dhe holivare. Doli qĂ« nĂ« komitet janĂ« gjithashtu njerĂ«z tĂ« gjallĂ«, tĂ« cilĂ«t mund tĂ« kenĂ« tĂ« papĂ«rshtatshme ose tĂ« panjohura pĂ«r disa gjĂ«ra.
PĂ«r ata qĂ« pĂ«lqejnĂ« holivaret pĂ«r arsyet e duhura, mbetet ngjarja e tretĂ« â sesioni BOF "Go kundĂ«r C++". Marrim njĂ« adhurues tĂ« Go, njĂ« adhurues tĂ« C++, pĂ«rpara se tĂ« fillojnĂ« seancĂ«n ata pĂ«rgatitin sĂ« bashku 100500 slide pĂ«r temĂ«n (siç janĂ« problemet me paketat nĂ« C++ ose mungesa e gjenerikĂ«ve nĂ« Go), dhe mĂ« pas diskutojnĂ« me zĂ« tĂ« lartĂ« midis tyre dhe me sallĂ«n, ndĂ«rsa salla pĂ«rpiqet tĂ« kuptojĂ« dy kĂ«ndvĂ«shtrime tĂ« ndryshme. NĂ«se fillojnĂ« njĂ« holivar pa arsye â moderatorĂ«t ndĂ«rhyjnĂ« dhe pajtojnĂ« palĂ«t. Ky format zgjat: disa orĂ« pas fillimit, vetĂ«m gjysma e slide-ve u kalua. Pjesa e fundit u detyrua tĂ« pĂ«rshpejtohej.
Stendat e partnerëve
Në hollin e konferencës, partnerët e saj ishin të pranishëm - në stendat e tyre tregonin për projektet aktuale, ofronin mundësi stazhesh dhe punësimi, organizonin kuize dhe garat të vogla, si dhe shpërndanin çmime të këndshme. Disa kompani madje ofronin mundësinë për të kaluar etapat fillestare të intervistave, që mund të ishte e dobishme për ata që kishin ardhur jo vetëm për të dëgjuar referatet.
Detajet teknike të referateve
Ne dëgjuam referatet gjatë të dy ditëve. Ndonjëherë ishte e vështirë të zgjidhnim një referat për shkak të disa që zhvilloheshin paralelisht - u dakorduam të ndaheshim dhe të shkëmbenim njohuritë e fituara në pushime. Edhe kështu, duket se shumë gjëra janë humbur. Këtu do të dëshironim të flisnim për përmbajtjen e disa referateve që na dukeshin më interesante.
Përjashtimet në C++ përmes optimizimeve të kompajlerit, Roman Rusyaev

Slide nga
Siç tregohet nga titulli, Roman shqyrtoi punën me përjashtime duke përdorur LLVM si shembull. Për ata që nuk e përdorin Clang në punën e tyre, referati mund të ofrojë gjithashtu një pasqyrë mbi mënyrën se si mund të optimizohet kodin. Kjo është për shkak se zhvilluesit e kompajlerëve dhe bibliotekave standarte komunikojnë me njëri-tjetrin, dhe shumë zgjidhje të suksesshme mund të përputhen.
Pra, për të trajtuar një përjashtim kërkohen disa veprime: thirrja e kodit të trajtimit (nëse ekziston) ose çlirimi i burimeve në nivelin aktual dhe rrotullimi i stack-ut më lart. Të gjitha kjo çon në atë që për thirrjet që potencialisht mund të gjenerojnë përjashtime, kompajleri shton instruksione të tjera. Prandaj, nëse përjashtimi në fakt nuk do të ndodhte, programi do të vazhdojë të kryejë veprime të panevojshme. Për të reduktuar kostot, në LLVM ekzistojnë disa heuristika për identifikimin e situatave ku nuk është e nevojshme të shtohet kodi për trajtimin e përjashtimeve ose ku mund të reduktohet numri i instruksioneve "të tepërta".
Referuesi shqyrton rreth një duzinë të tillash dhe tregon si situatat ku ato ndihmojnë në përshpejtimin e ekzekutimit të programit, ashtu edhe ato ku këto metoda nuk janë të aplikueshme.
Kështu, Roman Rusyaev çon dëgjuesit në përfundimin se kodi që përmban punë me përjashtime, përherë nuk mund të ekzekutohet pa ndonjë kost të rëndësishme, dhe ofron këto këshilla:
- në zhvillimin e bibliotekave, është më mirë të hiqni dorë nga përjashtimet në parim;
- nëse përjashtimet janë të nevojshme, atëherë sa më shumë që të jetë e mundur, duhen shtuar modifikatorët noexcept (dhe const), në mënyrë që kompajleri të mund të optimizojë sa më shumë.
Në përgjithësi, referuesi konfirmoi mendimin se përjashtimet duhet të përdoren sa më pak ose madje të hiqen krejtësisht.
Prezantimet e referatit janë në dispozicion përmes lidhjes:
Generators, coroutines and other brain-unrolling sweetness, Adi Shavit

Slide nga
Një nga shumë referatet e kësaj konference, e dedikuar risive të C++20, mbeti në kujtesë jo vetëm për prezantimin e saj me ngjyra, por edhe për përshkrimin e qartë të problemeve ekzistuese me logjikën e trajtimit të koleksioneve (cikli for, callback-et).
Adi Shavit identifikon kĂ«to: metodat ekzistuese kalojnĂ« tĂ« gjithĂ« koleksionin dhe nuk ofrojnĂ« qasje nĂ« njĂ« gjendje interim tĂ« brendshme (ose e ofrojnĂ« nĂ« rastin e callback-Ă«ve, por me shumĂ« efekte anĂ«sore tĂ« padĂ«shiruara, si Hell-i i Callback). Duket se ka iteraatorĂ«, por as me ata, nuk Ă«shtĂ« gjithçka aq e thjeshtĂ«: nuk ka pika tĂ« zakonshme hyrjeje dhe daljeje (begin â end kundrejt rbegin â rend dhe kĂ«shtu me radhĂ«), nuk Ă«shtĂ« e qartĂ« se sa do tĂ« iteronim? Duke filluar nga C++20, kĂ«to probleme zgjidhen!
Opcioni i parë: ranges. Me ndihmën e mbushjes mbi iteraatorët, ne marrim një ndërfaqe të përbashkët për fillimin dhe përfundimin e iteracionit, si dhe mundësi për kompozim. Të gjitha këto lejojnë ndërtimin e linjave të plota të trajtimit të të dhënave. Por ashtu si çdo gjë, nuk është gjithçka e lehtë: një pjesë e logjikës së llogaritjeve ndodhet brenda implementimit të iteraatorit specifik, që mund ta komplikohet kodin për tu kuptuar dhe për debuggim.

Slide nga
Ajo që do të thoja, për këtë rast në C++20 janë shtuar korutina (funksione, sjellja e të cilave është e ngjashme me gjeneratorët në gjuhën Python): ekzekutimi mund të shtyhet, duke kthyer një vlerë aktuale me ruajtjen e gjendjes interim. Në këtë mënyrë, ne arrijmë jo vetëm të punojmë me të dhënat ndërsa ato shfaqen, por gjithashtu inkapsulojmë gjithë logjikën brenda korutinës specifike.
Poros është një mangësi: për momentin ato mbështeten vetëm pjesërisht nga kompilatorët ekzistues, si dhe janë implementuar jo aq saktë sa do të dëshirohej: për shembull, për momentin nuk duhet të përdoren lidhjet dhe objektet temporale në korutina. Për më tepër, ka disa kufizime në atë që mund të jetë korutina, dhe funksionet constexpr, konstruktorët/destroktorët, si dhe main nuk përfshihen në këtë listë.
Prandaj, korutinat zgjidhin një pjesë të konsiderueshme të problemeve me thjeshtësinë e logjikës së përpunimit të të dhënave, por implementimet e tyre aktuale kërkojnë përmirësime.
Materialet:
- Prezantimet nga C++ Russia â
Truket e C++ nga Yandex.Taxi, Anton Polukhin
NĂ« profesionin tim ndonjĂ«herĂ« mĂ« duhet tĂ« realizoj gjĂ«ra thjesht ndihmĂ«se: njĂ« pĂ«rfaqĂ«sues midis ndĂ«rfaqes sĂ« brendshme dhe API-sĂ« sĂ« njĂ« biblioteke, regjistrimi ose analizimi. NĂ« kĂ«tĂ« rast, zakonisht nuk ka nevojĂ« pĂ«r optimizim tĂ« shtuar. Por çfarĂ« ndodh nĂ«se kĂ«to komponentĂ« pĂ«rdoren nĂ« disa nga shĂ«rbimet mĂ« tĂ« njohura nĂ« Runet? NĂ« njĂ« situatĂ« tĂ« tillĂ«, do tĂ« duhet tĂ« pĂ«rpunoni tera bajtĂ« çdo orĂ« vetĂ«m nga regjistrimet! AtĂ«herĂ« çdo milisekondĂ« ka rĂ«ndĂ«si dhe prandaj duhet tĂ« pĂ«rdoren trukĂ« tĂ« ndryshme â pĂ«r to fliste Anton Polukhin.
Mund tĂ« them se shembulli mĂ« interesant ishte implementimi i modelit pointer-to-implementation (pimpl).Â
#include <third_party/json.hpp> //PROBLEMS!Â
struct Value {Â
Value() = default;Â
Value(Value&& other) = default;Â
Value& operator=(Value&& other) = default;Â
~Value() = default;Â
std::size_t Size() const { return data_.size(); }Â
private:Â
third_party::Json data_;Â
};NĂ« kĂ«tĂ« shembull, nĂ« fillim do tĂ« dĂ«shironim tĂ« heqnim pĂ«rfshirjet e skedarĂ«ve tĂ« biblioteka tĂ« jashtme â kĂ«shtu qĂ« kompilimi do tĂ« jetĂ« mĂ« i shpejtĂ« dhe mund tĂ« sigurohemi nga konflikte tĂ« mundshme emĂ«ror dhe gabime tĂ« tjera tĂ« ngjashme.Â
MirĂ«, e transferuam #include nĂ« skedarin .cpp: duhet njĂ« forward-declaration tĂ« API-sĂ« tĂ« pĂ«rfshirĂ«, si dhe std::unique_ptr. Tani kemi alokime dinamike dhe gjĂ«ra tĂ« tjera tĂ« pakĂ«ndshme si tĂ« dhĂ«na tĂ« shpĂ«rndara nĂ« grumbull dhe garanca tĂ« ulta. Me tĂ« gjitha kĂ«to mund tĂ« ndihmojĂ« std::aligned_storage.Â
struct Value {
// ...
private:
using JsonNative = third_party::Json;
const JsonNative* Ptr() const noexcept;
JsonNative* Ptr() noexcept;
constexpr std::size_t kImplSize = 32;
constexpr std::size_t kImplAlign = 8;
std::aligned_storage_t data_;
};Problemi i vetĂ«m: duhet tĂ« specifikojmĂ« madhĂ«sinĂ« dhe pĂ«rmirĂ«simin pĂ«r çdo pĂ«rfaqĂ«sues â do ta bĂ«jmĂ« pimpl tonĂ« shabllon me parametra , ta pĂ«rdorim me disa vlera arbitrare dhe tĂ« shtojmĂ« nĂ« destruktorrin njĂ« kontroll qĂ« kemi gjithçka saktĂ«:Â
~FastPimpl() noexcept {
validate();
Ptr()->~T();
}
template
static void validate() noexcept {
static_assert(
Size == ActualSize,
"Madhësia dhe sizeof(T) nuk përputhen"
);
static_assert(
Alignment == ActualAlignment,
"Përmirësimi dhe alignof(T) nuk përputhen"
);
}Pasi gjatë përpunimit të destruktori T tashmë është i definuar, ky kod do të kuptojë saktësisht dhe në fazën e kompilimit do të shfaqë vlerat e nevojshme të madhësisë dhe përmirësimit që duhet të përfshihen. Kështu, me një ekzekutim shtesë të kompilimit, ne shkyçim alokimin dinamik të klasave që përfshihen, fshehim API-në në skedarin .cpp me implementimin, si dhe marrim një strukturë më të përshtatshme për cache nga procesori.
Regjistrimi dhe analizimi duken më pak impresionuese, prandaj nuk do të përmenden në këtë përmbledhje.
Prezantimet e referatit janë në dispozicion përmes lidhjes:
Teknikat moderne për të mbajtur kodin tuaj DRY, Björn Fahller
Në këtë prezantim, Björn Fahller tregon disa mënyra të ndryshme për të luftuar një gabim stilistik siç janë kontrollimet e përsëritura të kushteve:
assert(a == IDLE || a == CONNECTED || a == DISCONNECTED);E njohur? Duke pĂ«rdorur disa teknika tĂ« fuqishme tĂ« C++, tĂ« cilat janĂ« shfaqur nĂ« standardet e fundit, mund tĂ« implementoni me elegancĂ« tĂ« njĂ«jtĂ«n funksionalitet pa humbur asnjĂ« performancĂ«. Krahaso:  Â
assert(a == any_of(IDLE, CONNECTED, DISCONNECTED));PĂ«r tĂ« pĂ«rpunuar njĂ« numĂ«r tĂ« paqĂ«ndrueshĂ«m tĂ« kontrollimeve, pĂ«r tĂ« pĂ«rdorur template variadic dhe shprehjet e fold janĂ« tĂ« nevojshme. Le tĂ« supozojmĂ« se duam tĂ« kontrollojmĂ« barazimin e disa variablave me njĂ« element tĂ« enum state_type. E para qĂ« vjen nĂ« mend â tĂ« shkruajmĂ« njĂ« funksion ndihmĂ«s is_any_of:
enum state_type { IDLE, CONNECTED, DISCONNECTED };
template
bool is_any_of(state_type s, const Ts& ... ts) {
return ((s == ts) || ...);
}
Ky rezultat ndërmjetës shkakton zhgënjim. Deri tani kodi nuk bëhet më i lexueshëm:
assert(is_any_of(state, IDLE, DISCONNECTING, DISCONNECTED)); Pak pĂ«rmirĂ«sim nĂ« situatĂ« do tĂ« ndihmonin parametrat e shabllonĂ«ve non-type. Me ndihmĂ«n e tyre do tĂ« transferojmĂ« elementet e enum nĂ« listĂ«n e parametrave tĂ« shabllonit:Â
template
bool is_any_of(state_type t) {
return ((t == states) | ...);
}
assert(is_any_of(state)); Me përdorimin e auto në parametrin e shabllonit jo-type (C++17), qasja thjesht përfshihet në krahasime jo vetëm me elementët e state_type, por edhe me tipe primitive që mund të përdoren si parametra të shabllonëve non-type:
template
bool is_any_of(const T& t) {
return ((t == alternatives) | ...);
}Me rrjedhën e tillë të vazhdueshme përmirësimesh arrihet sintaksa e dëshiruar për verifikime:
template
struct any_of : private std::tuple {
// le të trashëgojmë konstruktorët nga tuple
using std::tuple::tuple;
template
bool operator ==(const T& t) const {
return std::apply(
[&t](const auto& ... ts) {
return ((ts == t) || ...);
},
static_cast<const std::tuple&>(*this));
}
};
template
any_of(Ts ...) -> any_of;
assert(any_of(IDLE, DISCONNECTING, DISCONNECTED) == state);
NĂ« kĂ«tĂ« shembull, udhĂ«zuesi i deduksionit shĂ«rben pĂ«r t'i treguar kompiluesit parametrat e dĂ«shiruar tĂ« modelit tĂ« strukturĂ«s, duke njohur tipet e argumenteve tĂ« konstruktorit.Â
MĂ« tutje â bĂ«het mĂ« interesante. Bjorn mĂ«son tĂ« generalizojĂ« kodin e marrĂ« pĂ«r operatorĂ«t e krahasimit pĂ«rveç ==, dhe mĂ« pas pĂ«r operacione tĂ« rastit. GjatĂ« procesit, shpjegohen karakteristika tĂ« tilla si atributi no_unique_address (C++20) dhe parametrat e modelit nĂ« funksionet lambdĂ« (C++20). (Po, tani sintaksa e lambdĂ«s Ă«shtĂ« akoma mĂ« e lehtĂ« pĂ«r t'u mbajtur mend â janĂ« katĂ«r çifte rreshtash tĂ« gjitha llojeve.) Zgjidhja pĂ«rfundimtare qĂ« pĂ«rdor funksionet si komponentĂ« tĂ« konstruktorit mĂ« ngroh shpirtin, pa pĂ«rmendur shprehjen tuple nĂ« traditat mĂ« tĂ« mira tĂ« llogaritjes lambdĂ«.
Në fund, mos harro të pastrosh!
- Le tĂ« kujtojmĂ« se lambdat janĂ« constexpr falas;Â
- Të shtojmë perfect forwarding dhe ta shohim sintaksën e tij të shëmtuar në lidhje me parameter pack në kapjen e lambdave;
- TĂ« japim kompiluesit mĂ« shumĂ« mundĂ«si pĂ«r optimizime me conditional noexcept;Â
- TĂ« kujdesemi pĂ«r njĂ« raportim mĂ« tĂ« qartĂ« tĂ« gabimeve nĂ« modelet duke parĂ« vlerat e kthimit eksplicite tĂ« lambdave. Kjo do tĂ« detyrojĂ« kompiluesin tĂ« bĂ«jĂ« mĂ« shumĂ« kontrollime pĂ«rpara thirrjes sĂ« funksionit tĂ« modelit â nĂ« fazĂ«n e verifikimit tĂ« tipit.Â
PĂ«r detaje shtoni referencat nĂ« materialet e ligjĂ«ratĂ«s:Â
- Prezentimi i slides:
Përshtypjet tona
Pjesëmarrja jonë e parë në C++ Russia u mbajte mend për ngjeshjen e saj. U formua përshtypja për C++ Russia si një ngjarje e ngrohtë, ku kufiri mes mësimit dhe komunikimit të drejtpërdrejtë ishte thuajse i papërfillshëm. E gjithë gjendja, nga motivimi i folësve deri te garat nga partnerët e ngjarjes, nxit të diskutohen në mënyrë aktive. Pjesa informuese e konferencës, e përbërë nga ligjërata, mbulon një gamë të gjerë temash duke përfshirë risitë në C++, shembuj nga praktika e projekteve të mëdha dhe konsiderata arkitekturore ideologjike. Por do të ishte e padrejtë të injorosh në aspektin social të ngjarjes, që ndihmon në kapërcimin e barrierave gjuhësore jo vetëm në lidhje me C++.
Faliminderit organizatorëve të konferencës për mundësinë për të marrë pjesë në një ngjarje të tillë!
Postimi i organizatorëve mbi të kaluarën, të tashmen dhe të ardhmen e C++ Russia mund të keni parë .
Faleminderit për leximin, dhe shpresojmë që përmbledhja jonë e ngjarjeve ishte e dobishme!
Burimi: habr.com
