Nëse në fillim të dramës thoni se në mur është një kod në C++, atëherë deri në fund ai patjetër duhet të ju dëmtojë.
Bjarne Stroustrup
Nga 31 tetori deri mĂ« 1 nĂ«ntor nĂ« ShĂ«n PETĂRBURG, u zhvillua konferenca C++ Russia Piter â njĂ« nga konferencat mĂ« tĂ« mĂ«dha pĂ«r programimin nĂ« Rusi, e organizuar nga JUG Ru Group. Mes folĂ«sve tĂ« ftuar ishin anĂ«tarĂ« tĂ« komitetit tĂ« standardizimit tĂ« C++, ligjĂ«rues nga CppCon, autorĂ« librash nga shtĂ«pia botuese OâReilly, si dhe mirĂ«mbajtĂ«s tĂ« projekteve tĂ« tilla si LLVM, libc++ dhe Boost. Konferenca ishte e orientuar ndaj zhvilluesve tĂ« shkĂ«lqyer nĂ« C++ qĂ« dĂ«shirojnĂ« tĂ« thellojnĂ« ekspertizĂ«n e tyre dhe tĂ« shkĂ«mbejnĂ« pĂ«rvoja nĂ« njĂ« komunikim tĂ« drejtpĂ«rdrejtĂ«. StudentĂ«t, doktorantĂ«t dhe mĂ«suesit e universiteteve ofrohen zbritje shumĂ« tĂ« kĂ«ndshme.
Botimi i konferencĂ«s nĂ« MoskĂ« do tĂ« mund tĂ« vizitohet qĂ« nĂ« prill tĂ« vitit tĂ« ardhshĂ«m, ndĂ«rsa tanimĂ« studentĂ«t tanĂ« do tĂ« tregojnĂ« se çfarĂ« interesante kanĂ« mĂ«suar nga ngjarja e kaluar.Â

Foto nga
NĂ« lidhje me ne
PĂ«r kĂ«tĂ« post punuan dy studentĂ« nga NIU HSE â ShĂ«n Petersburg:
- Liza Vasilenko â studente nĂ« vitin e katĂ«rt tĂ« bachelorit, qĂ« studion drejtimin 'GjuhĂ«t e Programimit' nĂ« kuadĂ«r tĂ« programit 'Matematika e aplikuar dhe InformaticĂ«'. Pas njohjes me gjuhĂ«n C++ nĂ« vitin e parĂ« tĂ« universitetit, mĂ« vonĂ« fitoi pĂ«rvojĂ« pune me tĂ« nĂ« praktikĂ« nĂ« industri. Pasioni pĂ«r gjuhĂ«t e programimit nĂ« pĂ«rgjithĂ«si dhe programimin funksional nĂ« veçanti ka ndikuar nĂ« zgjedhjen e ligjĂ«ratave nĂ« konferencĂ«.
- Danya Smirnov â student nĂ« vitin e parĂ« tĂ« masterit nĂ« 'Programim dhe AnalizĂ« tĂ« DhĂ«nash'. Edhe nĂ« shkollĂ« shkruante detyra olimpike nĂ« C++, dhe mĂ« tej ndodhi qĂ« gjuhĂ« tĂ« shfaqej vazhdimisht nĂ« aktivitetet e studimeve dhe pĂ«rfundimisht u bĂ« gjuha kryesore e punĂ«s. Vendosi tĂ« marrĂ« pjesĂ« nĂ« konferencĂ« pĂ«r tĂ« pĂ«rmirĂ«suar njohuritĂ« e tij dhe gjithashtu pĂ«r tĂ« mĂ«suar mbi mundĂ«sitĂ« e reja.
Në dërgimin e informacionit, drejtoria e fakultetit shpesh ndan informacion rreth ngjarjeve edukative të lidhura me specialitetin tonë. Në shtator pamë informacionin për C++ Russia dhe vendosëm të regjistrohemi si dëgjues. Ky është eksperienca jonë e parë në pjesëmarrjen në konferenca të tilla.
Struktura e konferencës
Ligjëratat
Brenda dy të dy ditëve, ekspertët lexuan 30 referate, duke ndriçuar shumë tema interesante: aplikimet e zgjuara të veçorive të gjuhës për zgjidhjen e problemeve praktike, përditësimet e ardhshme të gjuhës në lidhje me standardin e ri, kompromiset në dizajnin e C++ dhe masat paraprake për të punuar me pasojat e tyre, shembuj të arkitekturave interesante të projekteve, si dhe disa detaje nën kapak për infrastrukturën e gjuhës. Njëkohësisht, zhvilloheshin 3 prezantime, shpesh dy në rusisht dhe një në anglisht.
Zonat e diskutimit
Pas prezantimeve, të gjitha pyetjet e paqëna dhe diskutimet e papërfunduara kaloheshin në zona të veçanta komunikimi me prezantuesit, të pajisura me bordet për shkrim. Një mënyrë e shkëlqyer për të kaluar pushimin midis prezantimeve me një bisedë të këndshme.
Lightning Talks dhe diskutime informale
Nëse dëshironi të bëni një prezantim të shkurtër, mund të regjistroheni në bordin për shkrim për Lightning Talk-in e mbrëmjes dhe të merrni pesë minuta kohë për të folur për çfarëdo që lidhet me temën e konferencës. Për shembull, një hyrje e shpejtë në sanitizers për C++ (për disa ishte një risi) ose një histori për një bug në gjenerimin e sinusoidës, i cili mund të dëgjohet vetëm, por nuk mund të shihet.
Formati tjetër është paneli diskutues "Me Komitetin për Shpirtrat". Në skenë janë disa anëtarë të komitetit të standardizimit, në projektor është një oxhak (zyrtarisht për të krijuar një atmosferë të ngrohtë, por arsyeja "sepse gjithçka është në flakë" duket më argëtuese), pyetje janë rreth standardit dhe vizionit të përgjithshëm për C++, pa diskutime teknike të nxehta dhe polemika. U zbulua se në komitet ka edhe njerëz të gjallë që mund të jenë të pasigurt për diçka ose të mos dinë ndonjë gjë.
PĂ«r ata qĂ« duan polemika, ngeli njĂ« ngjarje tjetĂ«r â sesioni BOF "Go kundĂ«r C++". Merrni njĂ« adhurues tĂ« Go, njĂ« adhurues tĂ« C++, pĂ«rpara se tĂ« fillojĂ« sesioni ata bashkĂ« pĂ«rgatitin 100500 diapozitivĂ« mbi temĂ«n (siç janĂ« problemet me paketat nĂ« C++ ose mungesa e gjenerikĂ«ve nĂ« Go), dhe mĂ« pas ata diskutojnĂ« aktivisht me njĂ«ri-tjetrin e me audiencĂ«n, ndĂ«rsa audienca pĂ«rpiqet tĂ« kuptojĂ« dy kĂ«ndvĂ«shtrime njĂ«kohĂ«sisht. NĂ«se fillon njĂ« polemikĂ« jashtĂ« teme â moderatori intervin dhe pajton palĂ«t. Ky format Ă«shtĂ« i ngjashĂ«m: disa orĂ« pas fillimit, ishin kaluar vetĂ«m gjysmĂ«n e diapozitivĂ«ve. Fundi u detyrua tĂ« pĂ«rshpejtohej shumĂ«.
Standet e partnerëve
NĂ« hollin u paraqitĂ«n partnerĂ«t e konferencĂ«s â nĂ« stendat u treguan projektet aktuale, ofruan praktika dhe mundĂ«si punĂ«simi, organizuan kuize dhe garat tĂ« vogla, si dhe dhanĂ« dhurata tĂ« kĂ«ndshme. Disa kompani madje ofruan tĂ« kalonin fazat fillestare tĂ« intervistave, gjĂ« qĂ« mund tĂ« jetĂ« e dobishme pĂ«r ata qĂ« erdhĂ«n jo vetĂ«m pĂ«r tĂ« dĂ«gjuar prezantimet.
Detajet teknike të prezantimeve
Ne dĂ«gjuam prezantimet pĂ«r tĂ« dy ditĂ«t. NganjĂ«herĂ« ishte e vĂ«shtirĂ« tĂ« zgjidhje njĂ« prezantim nga ato qĂ« zhvillonin paralelisht â ne ranĂ« dakord tĂ« ndaheshim dhe tĂ« bashkĂ«punohej nĂ« periudhat ndĂ«rmjet. Edhe kĂ«shtu, duket se shumĂ« ka mbetur pa u pĂ«rmendur. KĂ«tu do tĂ« dĂ«shironim tĂ« flasim pĂ«r pĂ«rmbajtjen e disa prezantimeve qĂ« na dukeshin mĂ« interesante.
Përjashtimet në C++ përmes optimizimeve të kompiluesit, Roman Ruseajev

Slide nga
Ashtu siç kuptohet nga titulli, Roman shqyrtoi punën me përjashtimet duke përdorur shembuj të LLVM. Megjithatë, për ata që nuk përdorin Clang në punën e tyre, prezantimi mund të japë një pasqyrë të asaj se si kodi mund të optimizohet potencialisht. Kjo ndodh sepse zhvilluesit e kompiluesve dhe biblioteka standarde përkatëse komunikojnë me njëri-tjetrin dhe shumë zgjidhje të suksesshme mund të përputhen.
Pra, pĂ«r tĂ« trajtuar njĂ« pĂ«rjashtim Ă«shtĂ« e nevojshme tĂ« bĂ«hen shumĂ« veprime: tĂ« thirret kodi i trajtimit (nĂ«se ka) ose tĂ« lirohen burimet nĂ« nivelin aktual dhe tĂ« çlirohet staku mĂ« lart. E gjithĂ« kjo çon nĂ« atĂ« qĂ« pĂ«r thirrjet qĂ« potencialisht mund tĂ« japin pĂ«rjashtime, kompajleri shton instruksione shtesĂ«. Prandaj, nĂ«se nĂ« fakt pĂ«rjashtimi nuk do tĂ« thirret, programi do tĂ« vazhdojĂ« tĂ« ekzekutojĂ« veprime tĂ« panevojshme. PĂ«r tĂ« ulur ndarjen e kostove, nĂ« LLVM ka disa heuristika pĂ«r tĂ« pĂ«rcaktuar situatat ku kodi i trajtimit tĂ« pĂ«rjashtimeve nuk Ă«shtĂ« i nevojshĂ«m ose ku mund tĂ« ulet numri i instruksioneve âtĂ« panevojshmeâ.
Prezantuesi shqyrton rreth dhjetë prej tyre dhe tregon si situatat ku ato ndihmojnë në përshpejtimin e ekzekutimit të programit, ashtu edhe ato ku këto metoda nuk janë të aplicueshme.
Kështu, Roman Ruseajev e çon publikun në përfundimin se kodi që përmban punën me përjashtimet, aspak gjithmonë mund të ekzekutohet me kostot të zero, dhe jep këto këshilla:
- Kur zhvilloni biblioteka, duhet të hiqni dorë nga përjashtimet në parim;
- nëse përjashtimet janë të nevojshme, gjithmonë duhet të shtoni modifikatorët noexcept (dhe const), në mënyrë që kompajleri të mund të optimizojë sa më shumë.
Në përgjithësi, folësi konfirmoi mendimin se përjashtimet është më mirë t'i përdorim sa më pak ose të heqim dorë nga to krejtësisht.
Prezantimi i slides është i disponueshëm në lidhje:
Generatoret, korutinat dhe ëndrrat e tjera, Adi Shavit

Slide nga
Një nga shumë prezantimet e kësaj konference, e cila ishte e dedikuar novatoreve C++20, mbeti në kujtesë jo vetëm për prezantimin e saj të mirë, por edhe për shpjegimin e qartë të problemeve ekzistuese me logjikën e përpunimit të koleksioneve (cikli for, callback-e).
Adi Shavit identifikon kĂ«to probleme: metodat aktuale kalojnĂ« tĂ« gjithĂ« koleksionin dhe nuk ofrojnĂ« akses nĂ« njĂ« gjendje tĂ« brendshme ndĂ«rmjetĂ«se (ose e bĂ«jnĂ« kĂ«tĂ« nĂ« rastin e callback-eve, por me shumĂ« efekte anĂ«sore tĂ« pakĂ«ndshme, si Callback Hell). Duket se ka iteratorĂ«, por as me ata nuk Ă«shtĂ« aq e lehtĂ«: nuk ka pĂ«rputhje tĂ« pĂ«rbashkĂ«t tĂ« pikĂ«s sĂ« hyrjes dhe daljes (begin â end kundrejt rbegin â rend dhe kĂ«shtu me radhĂ«), nuk kuptohet se sa shumĂ« do tĂ« iterojmĂ«? Duke filluar nga C++20, kĂ«to probleme zgjidhen!
Opcioni i parë: ranges. Duke u mbështetur në iteratorët, ne marrim një ndërfaqe të përbashkët për fillimin dhe përfundimin e iterimit, si dhe mundësinë e kompozitës. Të gjitha këto lejojnë ndërtimin e lehtë të konvejereve të plota për përpunimin e të dhënave. Por nuk është gjithçka aq e lehtë: një pjesë e logjikës së llogaritjeve ndodhet brenda realizimit të iteratorit specifik, gjë që mund ta komplikohet kodin për t'u kuptuar dhe debug-uar.

Slide nga
ĂfarĂ« mund tĂ« themi, pĂ«r kĂ«tĂ« rast nĂ« C++20 janĂ« shtuar korutinat (funksione, sjellja e tĂ« cilave Ă«shtĂ« e ngjashme me generatoret nĂ« gjuhĂ«n Python): ekzekutimi mund tĂ« shtyhet, duke kthyer njĂ« vlerĂ« aktuale me ruajtjen e gjendjes ndĂ«rmjetĂ«se. KĂ«shtu, ne arrijmĂ« jo vetĂ«m tĂ« punojmĂ« me tĂ« dhĂ«nat pas paraqitjes sĂ« tyre, por gjithashtu inkapsulojmĂ« tĂ« gjithĂ« logjikĂ«n brenda çdo korutine specifike.
Por një lugë katran: në momentin e tanishëm, ato mbështeten vetëm pjesërisht nga kompilatorët aktualë, si dhe janë implementuar jo aq me kujdes siç do të dëshironim: për shembull, aktualisht nuk duhet të përdoren në korutina referencat dhe objektet e përkohshme. Plus, ka disa kufizime se çfarë mund të jetë korutina, dhe funksionet constexpr, konstruktorët/destruktoret, si dhe main nuk janë pjesë e këtij listës.
Kështu, korutinat zgjidhin një pjesë të dukshme të problemeve me thjeshtësinë e logjikës së përpunimit të të dhënave, por implementimet e tyre aktuale kërkojnë përmirësim.
Materialet:
- Slidat nga C++ Russia â
Truket C++ nga Yandex.Taxi, Anton Polukhyn
Në aktivitetin tim profesional, ndonjëherë duhet të realizoj gjëra krejt ndihmëse: një mbështetje midis ndërfaqes së brendshme dhe API-të e ndonjë biblioteke, regjistrimi ose analizimi. Në këtë rast, zakonisht nuk ka nevojë për ndonjë optimizim të mëtejshëm. Por çfarë ndodh nëse këto komponente përdoren në disa nga shërbimet më të njohura në Runet? Në këtë situatë do të duhet të përpunojmë terabajt në orë vetëm për regjistrimet! Atëherë çdo milisekondë është e rëndësishme dhe prandaj duhet të përdorim truke të ndryshme - për to ka folur Anton Polukhyn.
Mendoj 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, fillimisht duam tĂ« heqim dorĂ« nga skedarĂ«t e kokĂ«s sĂ« biblioteka tĂ« jashtme - kĂ«shtu qĂ« do tĂ« kompilojmĂ« mĂ« shpejt, dhe gjithashtu mund tĂ« sigurojmĂ« veten nga konflikte tĂ« mundshme emrash dhe gabimesh tĂ« tjera tĂ« ngjashme.Â
MirĂ«, e kemi transferuar #include nĂ« skedarin .cpp: na nevojitet njĂ« deklaratĂ« paraprake e API-t tĂ« mbĂ«shtjellĂ«, si dhe std::unique_ptr. Tani kemi alokime dinamike dhe gjĂ«ra tĂ« tjera tĂ« pakĂ«ndshme si tĂ« dhĂ«nat tĂ« shpĂ«rndara nĂ« grumbull dhe garancitĂ« e reduktuara. Me tĂ« gjitha kĂ«to mund tĂ« ndihmojĂ« std::aligned_storage.Â
struct Vlera {Â
// ...Â
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Ă« tregojmĂ« pĂ«r çdo mbĂ«shtjellĂ«s madhĂ«sinĂ« dhe pĂ«rputhshmĂ«rinĂ« - do ta bĂ«jmĂ« pimpl-in tonĂ« tĂ« shabllonit me parametra , do ta pĂ«rdorim me disa vlera arbitrare dhe do tĂ« shtojmĂ« nĂ« destruktorin verifikimin se e kemi gjetur gjithçka saktĂ«:Â
~FastPimpl() noexcept {Â
validate();Â
Ptr()->~T();Â
}
template
static void validate() noexcept {Â
static_assert(
Size == ActualSize,Â
"Size and sizeof(T) mismatch"
);Â
static_assert(
Alignment == ActualAlignment,Â
"Alignment and alignof(T) mismatch"
);Â
}Dukezh të mërzitshme ky kod do të trajtojë saktë duke u përpunuar në fazën e kompilimit dhe do të prodhojë vlerat e nevojshme të madhësisë dhe grumbullimit, të cilat duhet të shkruhen. Kështu, me një qëllim të vetëm shtesë të kompilimit, ne eliminojmë alokimin dinamik të klasave të mbuluara, fshehim API-në në skedarin .cpp me implementimin, si dhe fitojmë një strukturë më të përshtatshme për keƥimin nga procesori.
Regjistrimi dhe analizimi dukeshin më pak të impresionuese, dhe për këtë arsye nuk do të përmenden në këtë shqyrtim.
Prezantimi i slides është i disponueshëm në lidhje:
Teknikat moderne për të mbajtur kodin tuaj DRY, Björn Fahller
Në këtë referat, Björn Fahller tregon disa mënyra të ndryshme për të luftuar një gabim stilistik siç janë kontrollet e përsëritura të kushteve:
assert(a == IDLE || a == CONNECTED || a == DISCONNECTED);E njohur? Duke pĂ«rdorur disa teknikĂ« tĂ« fuqishme tĂ« C++, tĂ« cilat janĂ« shfaqur nĂ« standardet e fundit, mund tĂ« realizoni funksionalitetin e njĂ«jtĂ« nĂ« mĂ«nyrĂ« elegante pa ndonjĂ« humbje tĂ« performancĂ«s. Krahasoni:  Â
assert(a == any_of(IDLE, CONNECTED, DISCONNECTED));PĂ«r tĂ« trajtuar njĂ« numĂ«r tĂ« panatyrshĂ«m tĂ« kontrolleve, kĂ«rkohet pĂ«rdorimi i shablloneve variadic dhe shprehjeve tĂ« mbĂ«shtjella. Le tĂ« supozojmĂ« se duam tĂ« kontrollojmĂ« barazinĂ« e disa variablave me njĂ« element tĂ« enumât state_type. E para qĂ« na vjen nĂ« mendje â 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. Përsëri, kodi nuk bëhet më i lexueshëm:
assert(is_any_of(state, IDLE, DISCONNECTING, DISCONNECTED)); Pak pĂ«rmirĂ«sim nĂ« situatĂ« do tĂ« ndihmojnĂ« parametrat non-type tĂ« shablloneve. Me ndihmĂ«n e tyre, do ta transferojmĂ« elementet e enum nĂ« listĂ«n e parametrave tĂ« shablloneve:Â
template
bool is_any_of(state_type t) {Â
return ((t == states) | ...);Â
}
assert(is_any_of(state)); Me përdorimin e auto në parametrin jo-të tipit të shabllonit (C++17), qasja vetëm sa e përgjithëson atë për krahasimet, jo vetëm me elementet e state_type, por edhe me tipet primitive, të cilat mund të përdoren si parametra non-type shablloni:
template
bool is_any_of(const T& t) {
return ((t == alternatives) | ...);
}Me përmirësime të tilla të njëpasnjësh, arrihet sintaksa e dëshiruar e rrjedhshme për kontrollin:
template
struct any_of : private std::tuple {
// le të trashëgojmë konstruktoret 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Ă« sugjeruar parametrat e dĂ«shiruar tĂ« template qĂ« kompajleri tĂ« njohĂ« llojet e argumenteve tĂ« konstruktorit.Â
MĂ« pas â bĂ«het mĂ« interesante. Bjorn na mĂ«son tĂ« pĂ«rgjithĂ«sojmĂ« kodin e fituar pĂ«r operatorĂ«t e krahasimit pĂ«rveç ==, dhe mĂ« pas edhe pĂ«r operacione tĂ« rastĂ«sishme. Parallaxa pĂ«rdorimit shpjegon karakteristika si no_unique_address attribute (C++20) dhe parametrat e templates nĂ« funksionet lambda (C++20). (Po, tani sintaksa e lambdave Ă«shtĂ« shumĂ« mĂ« e lehtĂ« pĂ«r t'u mbajtur mend â ka katĂ«r çifte tĂ« radhitur tĂ« thonjve tĂ« çdo lloji.) Zgjidhja pĂ«rfundimtare me pĂ«rdorimin e funksioneve si detaje tĂ« konstruktorit personalisht mĂ« ngroh shpirtin, pĂ«r tĂ« mos pĂ«rmendur shprehjen tuple nĂ« traditat mĂ« tĂ« mira tĂ« llogaritjes lambda.
Në fund, mos harxhoni të bëni rregullime:
- KujtojmĂ« se lambdave â constexpr falas;Â
- Shtojmë perfect forwarding dhe shohim sintaksën e tij të shëmtuar në lidhje me parameter pack në mbushjen e lambdave;
- DĂ«rgojmĂ« kompajlerin mĂ« shumĂ« mundĂ«si pĂ«r optimizimin me conditional noexcept;Â
- Kujdesemi pĂ«r njĂ« dalje mĂ« tĂ« qartĂ« tĂ« gabimeve nĂ« templates falĂ« vlerave tĂ« kthimit tĂ« qarta nga lambdat. Kjo do ta detyrojĂ« kompajlerin tĂ« bĂ«jĂ« mĂ« shumĂ« kontrolle para thirrjes sĂ« vĂ«rtetĂ« tĂ« funksionit template â nĂ« fazĂ«n e kontrollit tĂ« llojeve.Â
PĂ«r detaje, reference nĂ« materialet e ligjĂ«ratĂ«s:Â
- Prezantime të prezantimit:
Përvojat tona
Pjesa jonë e parë në C++ Russia mbeti e paharrueshme për nga intensiteti. U krijua përshtypja se C++ Russia ishte një ngjarje e ngrohtë, ku ndarja mes mësimit dhe bisedave të gjalla ishte pothuajse e padukshme. Gjithçka, nga fryma e prezantuesve deri te garat nga partnerët e ngjarjes, inkurajonte diskutime të ngjashme. Pjesa përmbajtësore e konferencës, e cila përfshin prezantime, mbulon një gamë të gjerë temash, duke përfshirë risitë në C++, shembuj nga praktika e projekteve të mëdha dhe konsiderata arkitektonike ideologjike. Por do të ishte e padrejtë të mos theksohej edhe aspekti social i ngjarjes, i cili ndihmon në kalimin e barrierave gjuhësore në lidhje jo vetëm me C++.
Faleminderit organizatorëve të konferencës për mundësinë për të marrë pjesë në një ngjarje të tillë!
Postimi i organizatorëve rreth së kaluarës, së tashmes dhe së ardhmes së C++ Russia e keni parë .
Faleminderit që e lexuat, dhe shpresojmë se përmbledhja jonë e ngjarjeve ishte e dobishme!
Burimi: habr.com
