C++ Academy · บทเรียน

การเขียน traits แบบกำหนดเอง

สร้าง type traits ของคุณเอง

บทเรียน 4 จาก 413 ขั้นตอน

การเขียน traits แบบกำหนดเอง เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

การสร้างคุณลักษณะของคุณเอง

เมื่อไลบรารีมาตรฐานไม่มีคำถามที่คุณต้องการ คุณสามารถเขียนคุณลักษณะแบบกำหนดเองได้ คุณลักษณะก็คือเทมเพลตที่เปิดเผย ::value หรือ ::type ออกมา

เทมเพลตหลัก + การทำให้เฉพาะทาง

รูปแบบมาตรฐานคือ เทมเพลตหลักที่มีค่าเริ่มต้นเป็น false พร้อมการทำให้เฉพาะทางที่ตรงกับชนิดที่สนใจและกำหนดค่าเป็น true

#include <iostream>
#include <type_traits>

template <typename T>
struct is_ptr : std::false_type {};

template <typename T>
struct is_ptr<T*> : std::true_type {};

int main() {
    std::cout << is_ptr<int>::value << "\n";
    std::cout << is_ptr<int*>::value << "\n";
    return 0;
}

การสืบทอดจาก integral_constant

เมื่อสืบทอดจาก std::true_type หรือ std::false_type คุณลักษณะของคุณจะได้รับสมาชิก value โดยอัตโนมัติ และทำงานเหมือนคุณลักษณะมาตรฐาน

ตัวตรวจจับคอนเทนเนอร์

ตรวจดูว่าชนิดหนึ่งมีลักษณะเป็นคอนเทนเนอร์หรือไม่โดยตรวจสอบสมาชิกที่ซ้อนอยู่ ในที่นี้เราทำให้เฉพาะทางเมื่อพบ typedef value_type ผ่านตัวช่วย

#include <iostream>
#include <vector>
#include <type_traits>

template <typename T, typename = void>
struct has_value_type : std::false_type {};

template <typename T>
struct has_value_type<T, std::void_t<typename T::value_type>> : std::true_type {};

int main() {
    std::cout << has_value_type<std::vector<int>>::value << "\n";
    std::cout << has_value_type<int>::value << "\n";
    return 0;
}

อธิบาย std::void_t

std::void_t<...> จะแปลงรายการชนิดที่ถูกต้องใด ๆ ให้เป็น void หากชนิดใดชนิดหนึ่งภายในไม่ถูกต้อง การทำให้เฉพาะทางนั้นจะถูกตัดออกผ่าน SFINAE ดังนั้น false_type ในเทมเพลตหลักจึงเป็นตัวที่ถูกเลือก

การตรวจจับฟังก์ชันสมาชิก

คุณสามารถตรวจดูว่าชนิดหนึ่งมี size() ที่เรียกใช้งานได้หรือไม่ โดยทดสอบนิพจน์ภายใน void_t

#include <iostream>
#include <string>
#include <type_traits>

template <typename T, typename = void>
struct has_size : std::false_type {};

template <typename T>
struct has_size<T, std::void_t<decltype(std::declval<T>().size())>> : std::true_type {};

int main() {
    std::cout << has_size<std::string>::value << "\n";
    std::cout << has_size<int>::value << "\n";
    return 0;
}

declval

std::declval<T>() สร้างค่าจำลองชนิด T ในบริบทที่ไม่มีการประเมินค่า ทำให้คุณเขียนนิพจน์ decltype ได้โดยไม่ต้องสร้างออบเจ็กต์

คุณลักษณะสำหรับแปลงชนิด

คุณลักษณะแบบกำหนดเองยังสามารถสร้างชนิดได้ด้วย คุณลักษณะนี้จะตัดชั้นตัวชี้ออกหนึ่งชั้น

#include <iostream>
#include <type_traits>

template <typename T>
struct remove_one_pointer { using type = T; };

template <typename T>
struct remove_one_pointer<T*> { using type = T; };

int main() {
    using R = remove_one_pointer<int*>::type;
    std::cout << std::is_same_v<R, int> << "\n";
    return 0;
}

การจัดเตรียมตัวช่วย _v และ _t

ทำให้สอดคล้องกับรูปแบบมาตรฐานโดยเพิ่มเทมเพลตตัวแปรและเทมเพลตนามแฝง

#include <iostream>
#include <type_traits>

template <typename T>
struct is_char : std::false_type {};
template <>
struct is_char<char> : std::true_type {};

template <typename T>
inline constexpr bool is_char_v = is_char<T>::value;

int main() {
    std::cout << is_char_v<char> << "\n";
    std::cout << is_char_v<int> << "\n";
    return 0;
}

รูปแบบการตรวจจับ

เทคนิค void_t สามารถขยายเป็น รูปแบบการตรวจจับ ได้ โดย std::is_detected แบบทดลองทำให้รูปแบบนี้เป็นทางการ แนวคิดของ C++20 ช่วยให้เรื่องส่วนใหญ่สะอาดและอ่านง่ายขึ้น

การทดสอบคุณลักษณะของคุณ

ตรวจสอบคุณลักษณะแบบกำหนดเองด้วย static_assert เพื่อให้การเปลี่ยนแปลงที่ทำให้พฤติกรรมถดถอยทำให้การสร้างโปรแกรมล้มเหลวทันที

#include <type_traits>

template <typename T>
struct is_void_like : std::false_type {};
template <>
struct is_void_like<void> : std::true_type {};

static_assert(is_void_like<void>::value);
static_assert(!is_void_like<int>::value);

int main() { return 0; }

ตรวจสอบอย่างรวดเร็ว

ทบทวนบทบาทของ std::void_t

สรุปทบทวน

คุณได้เรียนรู้การเขียนคุณลักษณะแบบกำหนดเอง

  • เทมเพลตหลักมีค่าเริ่มต้นเป็น false ส่วนการทำให้เฉพาะทางจะกำหนดค่าเป็น true
  • สืบทอดจาก true_type/false_type
  • void_t + declval เป็นกลไกของรูปแบบการตรวจจับ
  • เพิ่มตัวช่วย _v/_t และทดสอบด้วย static_assert
เริ่มต้นได้ฟรี

เรียนรู้ C++ ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
51
บทเรียน
203

คำถามที่พบบ่อย

บทเรียน “การเขียน traits แบบกำหนดเอง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเขียน traits แบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเขียน traits แบบกำหนดเอง”

สร้าง type traits ของคุณเอง คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การเขียน traits แบบกำหนดเอง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม

ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสอบถามชนิด
  2. การแปลงชนิด
  3. ตรรกะตามเงื่อนไข
  4. การเขียน traits แบบกำหนดเอง
← กลับไปที่ C++ Academy