Terakhir kali , kami menggunakan SFINAE untuk mendeteksi apakah suatu tipe memiliki definisi, dan kami menggunakannya dalam kombinasi dengan
if constexpr
dan
if constexpr
generik sehingga kode dapat menggunakan tipe itu jika didefinisikan, sementara masih diterima oleh kompiler (dan dibuang) ) jika jenisnya tidak ditentukan.
Namun, penggunaan kami memiliki beberapa masalah, beberapa gangguan kecil, beberapa lebih membuat frustrasi.
- Anda harus mengatakan
struct
sepanjang waktu. - Jika jenisnya tidak ada, tindakan penamaan itu menyebabkan jenis yang akan disuntikkan ke namespace saat ini , bukan namespace tempat Anda mengharapkan tipe tersebut.
- Anda harus menggunakan teknik
struct
dengan nama yang tidak memenuhi syarat. Anda tidak dapat menggunakannya untuk menyelidiki tipe yang tidak Anda impor ke namespace saat ini.
Kami dapat memperbaiki ketiga masalah dengan satu solusi: Memprediksi jenis di namespace yang diinginkan.

Setelah Anda melakukan ini, Anda tidak perlu mengatakan
struct
karena struct pasti telah dinyatakan. Penggunaan Anda sebagai parameter tipe templat di
call_if_defined
tidak akan membuat deklarasi baru, karena sudah dideklarasikan. Dan karena telah dinyatakan, Anda dapat mengaksesnya melalui nama yang tidak memenuhi syarat, nama namespace lengkapnya, atau apa pun di antaranya. Juga tipe alias atau tipe dependen. (Maaf, itu tidak ada di antaranya.)
namespace app { void foo() { call_if_defined<awesome::special>([&](auto* p) {
Bagi mereka yang telah mengikuti seri dari awal, Anda mungkin telah memperhatikan bahwa metode
call_if_defined
tidak cukup sama 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 if constexpr ((...)) terlihat aneh, tapi itu wajib. Tanda kurung luar diperlukan oleh pernyataan
if constexpr
, dan tanda kurung bagian dalam diperlukan oleh
ekspresi lipatan . Ekspresi lipatan diperluas ke
if constexpr ( (is_complete_type_v<T1> && is_complete_type_v<T2> && ... is_complete_type_v<Tn>))
Permintaan lambda menggunakan
ekspansi paket parameter :
lambda(static_cast<T*>(nullptr)...);
Ini berkembang menjadi
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 menulis ini sebagai
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 memberi nama jenis templat, dengan demikian menghemat kesulitan karena harus mengembalikannya dengan memainkan
std::decay_t
games.
Lain kali , kita akan menggunakan ini sebagai batu loncatan dan memperpanjang polanya.
Catatan untuk mereka yang tiba di sini melalui mesin pencari : Ini adalah bagian terakhir dari bagian inti dari seri, tetapi masih ada bagian yang akan datang. Untuk yang tidak sabar, berikut ini hal-hal yang harus disalin-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)...); } }
Omong-omong, kami memiliki lowongan yang keren [Dublin]
Havok telah menjadi yang terdepan dalam inovasi dalam pengembangan game dan 3D interaktif selama lebih dari satu dekade. Sebagai bagian dari Cognition, tim yang bertanggung jawab atas HoloLens, kami sekarang menggabungkan keahlian itu dengan kekuatan Azure Cloud untuk mengembangkan banyak layanan menarik yang mendorong pengalaman Realita Campuran seperti layanan Azure Remote Rendering yang baru diumumkan. Kami bersemangat tentang konvergensi teknologi AR, VR, dan cloud untuk memungkinkan terciptanya pengalaman Realita Campuran yang memukau.
Bekerja di Havok:- Anda akan bekerja dalam tim kecil yang berfokus dengan pengembang berbakat
- Anda akan memiliki kesempatan untuk bekerja dengan teknologi baru pada beragam platform dan perangkat keras terdepan
- Anda akan berupaya memecahkan masalah teknis yang menantang dengan cakupan luas
- Anda akan berkolaborasi dengan tim-tim berbakat di seluruh dunia
Tanggung jawab
- Desain, kembangkan, uji, dan berikan kode C ++ multiplatform berkualitas tinggi, efisien dan bersih
- Kembangkan layanan Azure yang sangat skalabel
- Bekerja secara langsung dengan pelanggan internal dan eksternal untuk mendorong pengembangan produk
Kualifikasi
- C ++ keterampilan coding dan debugging
- Kemampuan untuk bekerja di lingkungan tim berdasarkan basis kode bersama
- Pengalaman dengan teknologi cloud dan layanan terdistribusi (mis. Azure Batch, Azure Blob Storage, Docker, Telemetry)
Poin bonus
Ada banyak keterampilan lain yang tidak diperlukan, tetapi yang berharga di seluruh tim dan ini termasuk:
- C #, ASP.Net, JavaScript, TypeScript, React
- Mesin game Unity, Unreal atau terkait
- Pengalaman dalam 3D, AR, atau VR interaktif
- Layanan jaringan dan backend
- Optimalisasi kinerja
Anda dapat memperoleh informasi lebih lanjut dan mengirimkan CV Anda di
sini .