C ++, apakah jenisnya didefinisikan: deklarasi awal dari objek yang diperlukan

Terakhir kali , kami menggunakan SFINAE untuk mengetahui apakah suatu tipe memiliki definisi, dan kami menggunakannya dalam kombinasi dengan if constexpr dan ekspresi lambda generik sehingga kode dapat menggunakan tipe jika didefinisikan, sementara masih diterima oleh kompiler (dan dibuang) jika jenisnya tidak didefinisikan.

Namun, ada beberapa masalah dengan aplikasi ini:

  • Setiap kali Anda perlu menulis sebuah struct .
  • Jika jenisnya tidak ada, maka tetapkan namanya, tipe ini dimasukkan di namespace saat ini , dan bukan di namespace di mana Anda menginginkannya.
  • Anda perlu menggunakan struct dengan nama yang tidak memenuhi syarat. Anda tidak dapat menggunakannya untuk memeriksa jenis yang tidak Anda impor ke namespace saat ini.

Kami dapat memperbaiki ketiga masalah dengan satu solusi: pertama mendeklarasikan jenis di namespace yang diinginkan.



 // awesome.h namespace awesome { //      struct special { ... }; } //   namespace awesome { //   ,    struct special; } 

Setelah Anda melakukan ini, Anda tidak perlu menulis struct karena struktur telah dinyatakan. Menggunakannya sebagai parameter tipe templat di call_if_defined tidak akan mengarah pada pembuatan deklarasi baru, karena semuanya sudah dideklarasikan. Dan karena dia dinyatakan, Anda dapat mengaksesnya melalui namanya yang tidak memenuhi syarat, nama ruang nama lengkapnya, atau melalui apa pun di antaranya. Juga melalui tipe alias atau tipe dependen (sayangnya, mereka tidak ada di antara).

 namespace app { void foo() { call_if_defined<awesome::special>([&](auto* p) { //      "awesome::special" // .     "special" //     . using special = std::decay_t<decltype(*p)>; //      "special"   //   "awesome::special". special::do_something(); }); } } 

Mereka yang telah mengikuti seri artikel ini dari awal mungkin telah memperhatikan bahwa metode call_if_defined tidak cukup cocok dengan versi yang kami tulis sebelumnya. Versi baru mendukung beberapa parameter tipe dan memanggil lambda hanya jika semua tipe didefinisikan.

Mari kita lihat lebih dekat:

 template<typename... T, typename TLambda> void call_if_defined(TLambda&& lambda) { if constexpr ((... && is_complete_type_v<T>)) { lambda(static_cast<T*>(nullptr)...); } } 

Tanda kurung ganda di dalam jika constexpr ((...)) terlihat aneh, tetapi mereka diperlukan. Tanda kurung eksternal diperlukan oleh pernyataan if constexpr , dan tanda kurung internal diperlukan oleh ekspresi konvolusi . Ekspresi konvolusi meluas ke

  if constexpr ( (is_complete_type_v<T1> && is_complete_type_v<T2> && ... is_complete_type_v<Tn>)) 

Panggilan lambda menggunakan ekstensi paket parameter :

  lambda(static_cast<T*>(nullptr)...); 

Mengembang ke

  lambda(static_cast<T1*>(nullptr), static_cast<T2*>(nullptr), ..., static_cast<Tn*>(nullptr)); 

di mana static_cast<T*>(nullptr) diulangi sekali untuk setiap jenis.

Seperti yang saya sebutkan sebelumnya, kita dapat menggunakan fungsi ini untuk memanggil lambda jika semua tipe didefinisikan:

 void foo(Source const& source) { call_if_defined<special, magic>( [&](auto* p1, auto* p2) { using special = std::decay_t<decltype(*p1)>; using magic = std::decay_t<decltype(*p2)>; auto s = source.try_get<special>(); if (s) magic::add_magic(s); }); } 

C ++ 20 memungkinkan Anda untuk menulisnya seperti ini:

 void foo(Source const& source) { call_if_defined<special, magic>( [&]<typename special, typename magic> (special*, magic*) { auto s = source.try_get<special>(); if (s) magic::add_magic(s); }); } 

yang memungkinkan Anda untuk memberi nama jenis templat, sehingga menghilangkan kebutuhan untuk mengekstraksi ulang saat bermain dengan std::decay_t .

Pada artikel selanjutnya, kita akan menggunakan ini sebagai loncatan dan memperluas sirkuit.



Catatan : ini adalah bagian keempat dari seri utama artikel, tetapi masih ada bagian lain ( 1 , 2 , 3 , 5 ). Untuk yang tidak sabar: inilah yang perlu Anda salin dan tempel:

 template<typename, typename = void> constexpr bool is_type_complete_v = false; template<typename T> constexpr bool is_type_complete_v <T, std::void_t<decltype(sizeof(T))>> = true; template<typename... T, typename TLambda> void call_if_defined(TLambda&& lambda) { if constexpr ((... && is_complete_type_v<T>)) { lambda(static_cast<T*>(nullptr)...); } } 

Ngomong-ngomong, kita punya pekerjaan keren


Selama lebih dari satu dekade, Havok telah berada di garis depan inovasi dalam pengembangan game dan 3D interaktif. Sebagai bagian dari Cognition, tim HoloLens, kami sekarang menggabungkan keahlian ini dan kekuatan cloud Azure untuk mengembangkan banyak layanan realitas campuran baru yang menarik. Di antara mereka adalah layanan Azure Remote Rendering yang baru diumumkan. Kami bersemangat menggabungkan teknologi AR, VR dan cloud, yang bersama-sama memungkinkan kami untuk menciptakan praktik inovatif menggunakan realitas campuran.

Pekerjaan di Havok:

  • Anda akan bekerja dalam tim kecil dengan pengembang berbakat
  • Anda akan memiliki kesempatan untuk bekerja dengan teknologi baru di berbagai platform dan perangkat keras.
  • Anda akan berusaha memecahkan masalah teknis yang rumit dengan prospek yang luar biasa
  • Anda akan berkolaborasi dengan tim keren di seluruh dunia.

Tanggung jawab


  • Merancang, mengembangkan dan menguji kode C ++ multi-platform berkualitas tinggi, efisien dan bersih
  • Kembangkan layanan Azure yang dapat diskalakan dengan baik
  • Bekerja secara langsung dengan pelanggan internal dan eksternal untuk merangsang pengembangan produk

Kualifikasi


  • C ++ kemampuan pemrograman dan debugging
  • Kemampuan untuk bekerja dalam tim dengan kode umum
  • Pengalaman dengan cloud dan teknologi layanan terdistribusi (mis. Azure Batch, Azure Blob Storage, Docker, Telemetry)

Akan menjadi nilai tambah


  • C #, ASP.Net, JavaScript, TypeScript, React
  • Mesin game Unity, Unreal atau terkait
  • Alami 3D Interaktif, AR atau VR
  • Layanan jaringan dan server
  • Optimalisasi kinerja

Anda dapat mempelajari lebih lanjut dan mengirimkan aplikasi Anda di sini atau melalui LinkedIn .

Source: https://habr.com/ru/post/id459787/


All Articles