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

การทำให้เฉพาะทางบางส่วน

ทำให้รูปแบบเทมเพลตเฉพาะทาง

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

การทำให้จำเพาะบางส่วนคืออะไร

การทำให้จำเพาะบางส่วนเป็นการปรับแต่งแม่แบบสำหรับชนิดกลุ่มหนึ่งที่มีรูปแบบร่วมกัน แทนที่จะเป็นชนิดหนึ่งชนิดที่ตรงกันทุกประการ

  • รองรับเฉพาะแม่แบบคลาสเท่านั้น
  • คุณยังคงปล่อยให้พารามิเตอร์บางส่วนเป็นแบบทั่วไป
#include <iostream>

template <typename T>
struct Traits { static const char* kind() { return "value"; } };

template <typename T>
struct Traits<T*> { static const char* kind() { return "pointer"; } };

int main() {
    std::cout << Traits<int>::kind() << '\n';
    std::cout << Traits<int*>::kind() << '\n';
    return 0;
}

การจับคู่พอยน์เตอร์

รูปแบบ T* จับคู่กับชนิดพอยน์เตอร์ใด ๆ ทำให้คุณจัดการพอยน์เตอร์ทั้งหมดได้ด้วยการทำให้จำเพาะเพียงรายการเดียว

#include <iostream>

template <typename T>
struct Deref { static T get(T v) { return v; } };

template <typename T>
struct Deref<T*> { static T get(T* p) { return *p; } };

int main() {
    int x = 42;
    std::cout << Deref<int>::get(7) << '\n';
    std::cout << Deref<int*>::get(&x) << '\n';
    return 0;
}

ฟังก์ชันไม่สามารถทำให้จำเพาะบางส่วนได้

มีเพียงแม่แบบคลาส (และแม่แบบตัวแปร) เท่านั้นที่รองรับการทำให้จำเพาะบางส่วน สำหรับฟังก์ชัน ให้ใช้การโอเวอร์โหลดแทน

#include <iostream>

template <typename T>
void show(T) { std::cout << "value\n"; }

template <typename T>
void show(T*) { std::cout << "pointer\n"; }

int main() {
    int x = 0;
    show(5);
    show(&x);
    return 0;
}

การทำให้พารามิเตอร์หนึ่งจากสองพารามิเตอร์จำเพาะ

เมื่อมีพารามิเตอร์ชนิดหลายรายการ คุณสามารถกำหนดค่าหนึ่งรายการให้ตายตัวและปล่อยอีกรายการให้เปิดกว้าง เพื่อจับคู่รูปแบบที่ครอบคลุมชนิดต่าง ๆ

#include <iostream>

template <typename A, typename B>
struct Pair { static const char* kind() { return "mixed"; } };

template <typename A>
struct Pair<A, A> { static const char* kind() { return "same types"; } };

int main() {
    std::cout << Pair<int, double>::kind() << '\n';
    std::cout << Pair<int, int>::kind() << '\n';
    return 0;
}

การจับคู่แอเรย์

คุณสามารถจับคู่ชนิดแอเรย์ด้วยรูปแบบที่เก็บทั้งชนิดสมาชิกและขนาดไว้เป็นพารามิเตอร์ที่ไม่ใช่ชนิด

#include <iostream>

template <typename T>
struct Info { static int size() { return 1; } };

template <typename T, int N>
struct Info<T[N]> { static int size() { return N; } };

int main() {
    std::cout << Info<int>::size() << '\n';
    std::cout << Info<int[5]>::size() << '\n';
    return 0;
}

รูปแบบ const

การทำให้จำเพาะสามารถถอดหรือตรวจจับ const ได้ด้วยการจับคู่ const T เป็นรูปแบบ

#include <iostream>

template <typename T>
struct IsConst { static const bool value = false; };

template <typename T>
struct IsConst<const T> { static const bool value = true; };

int main() {
    std::cout << std::boolalpha;
    std::cout << IsConst<int>::value << '\n';
    std::cout << IsConst<const int>::value << '\n';
    return 0;
}

รายการที่จำเพาะที่สุดจะชนะ

เมื่อมีการทำให้จำเพาะหลายรายการที่อาจจับคู่ได้ คอมไพเลอร์จะเลือกรายการที่จำเพาะที่สุด ซึ่งเป็นรูปแบบที่เฉพาะเจาะจงที่สุด

#include <iostream>

template <typename T>
struct K { static int v() { return 0; } };

template <typename T>
struct K<T*> { static int v() { return 1; } };

template <>
struct K<int*> { static int v() { return 2; } };

int main() {
    std::cout << K<double*>::v() << ' ' << K<int*>::v() << '\n';
    return 0;
}

รูปแบบการอ้างอิง

คุณยังสามารถจับคู่ชนิดการอ้างอิงได้ เพื่อแยกการอ้างอิงออกจากค่าทั่วไป

#include <iostream>

template <typename T>
struct Cat { static const char* k() { return "value"; } };

template <typename T>
struct Cat<T&> { static const char* k() { return "lvalue ref"; } };

int main() {
    std::cout << Cat<int>::k() << '\n';
    std::cout << Cat<int&>::k() << '\n';
    return 0;
}

การสร้างคุณลักษณะของชนิด

การทำให้จำเพาะบางส่วนเป็นกลไกเบื้องหลังคุณลักษณะของชนิด ต่อไปนี้คือตัวอย่าง remove_pointer ที่เขียนขึ้นเอง

#include <iostream>
#include <type_traits>

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

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

int main() {
    std::cout << std::boolalpha;
    std::cout << std::is_same<RemovePtr<int*>::type, int>::value << '\n';
    return 0;
}

การรวมรูปแบบ

คุณสามารถผสมรูปแบบต่าง ๆ ได้ เช่น การจับคู่พอยน์เตอร์ไปยังค่าคงที่ เพื่อจัดการโครงสร้างชนิดแบบซ้อนชั้น

#include <iostream>

template <typename T>
struct Desc { static const char* k() { return "plain"; } };

template <typename T>
struct Desc<const T*> { static const char* k() { return "ptr to const"; } };

int main() {
    std::cout << Desc<int>::k() << '\n';
    std::cout << Desc<const int*>::k() << '\n';
    return 0;
}

คุณลักษณะของคอนเทนเนอร์ที่ใช้งานได้จริง

ใช้การทำให้จำเพาะบางส่วนเพื่อดึงชนิดสมาชิกของแม่แบบที่มีลักษณะคล้ายคอนเทนเนอร์ออกมา

#include <iostream>
#include <type_traits>

template <typename C>
struct Element { using type = void; };

template <template <typename> class C, typename T>
struct Element<C<T>> { using type = T; };

template <typename T>
struct Box { T item; };

int main() {
    std::cout << std::boolalpha;
    std::cout << std::is_same<Element<Box<int>>::type, int>::value << '\n';
    return 0;
}

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับการทำให้จำเพาะบางส่วน

สรุปทบทวน

คุณได้เรียนรู้เกี่ยวกับการทำให้จำเพาะบางส่วนดังนี้:

  • ปรับแต่งแม่แบบคลาสสำหรับรูปแบบของชนิด เช่น T* หรือ const T
  • ฟังก์ชันใช้การโอเวอร์โหลด ไม่ใช่การทำให้จำเพาะบางส่วน
  • เลือกเวอร์ชันที่ตรงกันและจำเพาะที่สุด
  • เป็นกลไกเบื้องหลังคุณลักษณะของชนิด เช่น remove_pointer

ถัดไป คุณจะได้เรียนรู้ SFINAE ซึ่งเป็นวิธีเปิดใช้ฟังก์ชันเฉพาะเมื่อชนิดนั้นมีคุณสมบัติตรงตามเงื่อนไข

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

บทเรียน “การทำให้เฉพาะทางบางส่วน” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การทำให้เฉพาะทางบางส่วน”

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

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

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

บทเรียน “การทำให้เฉพาะทางบางส่วน” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การทำให้เฉพาะทางแบบเต็ม
  2. การทำให้เฉพาะทางบางส่วน
  3. SFINAE
  4. รูปแบบ enable_if
← กลับไปที่ C++ Academy