การทำให้เฉพาะทางแบบเต็ม
ปรับแต่งเทมเพลตสำหรับชนิดหนึ่ง
การทำให้เฉพาะทางแบบเต็ม เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
สรุปทบทวน: แม่แบบ
แม่แบบช่วยให้โค้ดส่วนหนึ่งทำงานกับได้หลายชนิด คอมไพเลอร์จะสร้างเวอร์ชันที่เป็นรูปธรรมสำหรับแต่ละชนิดที่คุณใช้
- รูปแบบทั่วไปจัดการได้กับทุกชนิด
- บางครั้งชนิดหนึ่งจำเป็นต้องได้รับการจัดการเป็นพิเศษ
#include <iostream>
template <typename T>
T maxOf(T a, T b) { return a > b ? a : b; }
int main() {
std::cout << maxOf(3, 9) << ' ' << maxOf(2.5, 1.5) << '\n';
return 0;
}การทำให้จำเพาะอย่างสมบูรณ์คืออะไร
การทำให้จำเพาะอย่างสมบูรณ์จัดเตรียมการนำไปใช้งานที่แยกออกมาโดยสิ้นเชิงสำหรับชนิดใดชนิดหนึ่งโดยเฉพาะ เพื่อแทนที่แม่แบบทั่วไปสำหรับชนิดนั้นเท่านั้น
#include <iostream>
template <typename T>
void describe(T) { std::cout << "some type\n"; }
template <>
void describe(int) { std::cout << "an int\n"; }
int main() {
describe(3.14);
describe(42);
return 0;
}ไวยากรณ์
การทำให้จำเพาะอย่างสมบูรณ์จะเริ่มต้นด้วยวงเล็บแหลมว่าง template <> และระบุชนิดที่แน่นอนในการทำให้จำเพาะ
#include <iostream>
template <typename T>
struct TypeName { static const char* get() { return "unknown"; } };
template <>
struct TypeName<bool> { static const char* get() { return "bool"; } };
int main() {
std::cout << TypeName<double>::get() << '\n';
std::cout << TypeName<bool>::get() << '\n';
return 0;
}การทำให้แม่แบบคลาสจำเพาะ
คุณสามารถทำให้แม่แบบคลาสทั้งคลาสจำเพาะได้ ทำให้ชนิดนั้นมีสมาชิกและพฤติกรรมของตนเอง ซึ่งแตกต่างจากแม่แบบหลัก
#include <iostream>
template <typename T>
struct Storage {
T value;
void show() { std::cout << "value: " << value << '\n'; }
};
template <>
struct Storage<bool> {
bool value;
void show() { std::cout << (value ? "true" : "false") << '\n'; }
};
int main() {
Storage<int> s{5}; s.show();
Storage<bool> b{true}; b.show();
return 0;
}เหตุใดจึงต้องทำให้จำเพาะ
การทำให้จำเพาะช่วยจัดการชนิดที่ต้องใช้ตรรกะต่างออกไป เช่น const char* ที่ต้องเปรียบเทียบสตริงแทนการเปรียบเทียบพอยน์เตอร์
#include <iostream>
#include <cstring>
template <typename T>
bool equal(T a, T b) { return a == b; }
template <>
bool equal(const char* a, const char* b) { return std::strcmp(a, b) == 0; }
int main() {
std::cout << std::boolalpha;
std::cout << equal(5, 5) << '\n';
std::cout << equal("hi", "hi") << '\n';
return 0;
}การทำให้สมาชิกเดียวจำเพาะ
สำหรับแม่แบบคลาส คุณสามารถทำให้ฟังก์ชันสมาชิกเพียงตัวเดียวจำเพาะสำหรับชนิดที่กำหนด โดยนำส่วนที่เหลือกลับมาใช้ใหม่ได้
#include <iostream>
template <typename T>
struct Printer {
void print(T v) { std::cout << v << '\n'; }
};
template <>
void Printer<char>::print(char v) {
std::cout << "char: " << v << '\n';
}
int main() {
Printer<int>{}.print(7);
Printer<char>{}.print('A');
return 0;
}สิ่งที่ตรงกันย่อมชนะสิ่งทั่วไป
เมื่อมีการทำให้จำเพาะอย่างสมบูรณ์สำหรับชนิดที่ตรงกันทุกประการ คอมไพเลอร์จะเลือกใช้สิ่งนั้นก่อนแม่แบบหลักเสมอ
#include <iostream>
template <typename T>
int rank() { return 0; }
template <>
int rank<double>() { return 99; }
int main() {
std::cout << rank<int>() << ' ' << rank<double>() << '\n';
return 0;
}การทำให้จำเพาะต้องตามหลังแม่แบบหลัก
ต้องประกาศการทำให้จำเพาะหลังจากที่มองเห็นแม่แบบหลักแล้ว มิฉะนั้นคอมไพเลอร์จะไม่มีสิ่งใดให้ทำให้จำเพาะ
#include <iostream>
template <typename T>
const char* kind() { return "generic"; }
template <>
const char* kind<float>() { return "float"; }
int main() {
std::cout << kind<int>() << ' ' << kind<float>() << '\n';
return 0;
}การทำให้แม่แบบของ std จำเพาะ
คุณสามารถทำให้แม่แบบของไลบรารีมาตรฐานบางรายการ เช่น std::hash จำเพาะสำหรับชนิดของคุณเองได้ เพื่อให้ชนิดเหล่านั้นทำงานกับคอนเทนเนอร์แบบแฮชได้
#include <iostream>
struct Point { int x, y; };
template <typename T>
struct Hasher { size_t operator()(const T&) { return 0; } };
template <>
struct Hasher<Point> {
size_t operator()(const Point& p) { return p.x * 31 + p.y; }
};
int main() {
Hasher<Point> h;
std::cout << h(Point{2, 3}) << '\n';
return 0;
}การทำให้จำเพาะด้วยค่า
พารามิเตอร์แม่แบบที่ไม่ใช่ชนิดสามารถทำให้จำเพาะตามค่าเฉพาะได้ ซึ่งมีประโยชน์สำหรับตารางที่สร้างขณะคอมไพล์
#include <iostream>
template <int N>
struct Fib { static const int value = Fib<N-1>::value + Fib<N-2>::value; };
template <>
struct Fib<0> { static const int value = 0; };
template <>
struct Fib<1> { static const int value = 1; };
int main() {
std::cout << Fib<10>::value << '\n';
return 0;
}รักษาพฤติกรรมให้สอดคล้องกัน
การทำให้จำเพาะควรรักษาข้อตกลงเชิงแนวคิดเดียวกับแม่แบบหลักไว้ โดยเปลี่ยนเฉพาะการนำไปใช้เท่านั้น มิฉะนั้นผู้เรียกใช้อาจเกิดความประหลาดใจได้
#include <iostream>
template <typename T>
T zero() { return T{}; }
template <>
int zero<int>() { return 0; }
int main() {
std::cout << zero<int>() << ' ' << zero<double>() << '\n';
return 0;
}ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับไวยากรณ์ของการทำให้จำเพาะทั้งหมด
สรุปทบทวน
คุณได้เรียนรู้เกี่ยวกับการทำให้จำเพาะทั้งหมดดังนี้:
- จัดเตรียมการนำไปใช้เฉพาะสำหรับชนิดหนึ่งชนิดที่ตรงกันทุกประการ
- เขียนด้วย
template <>และชนิดรูปธรรม - คอมไพเลอร์จะเลือกการทำให้จำเพาะที่ตรงกันทุกประการก่อนเสมอ
- ใช้ได้กับฟังก์ชัน คลาส สมาชิกเดี่ยว และค่าเฉพาะ
ถัดไป คุณจะได้เรียนรู้การทำให้จำเพาะบางส่วน ซึ่งใช้จับคู่รูปแบบของชนิด
คำถามที่พบบ่อย
บทเรียน “การทำให้เฉพาะทางแบบเต็ม” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การทำให้เฉพาะทางแบบเต็ม” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การทำให้เฉพาะทางแบบเต็ม”
ปรับแต่งเทมเพลตสำหรับชนิดหนึ่ง คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การทำให้เฉพาะทางแบบเต็ม” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การทำให้เฉพาะทางแบบเต็ม
- การทำให้เฉพาะทางบางส่วน
- SFINAE
- รูปแบบ enable_if