Template C++ Là Gì – Sử Dụng Template Trong C++ Thế Nào (Phần 1)

Trong bài viết này mình sẽ hướng dẫn cách bạn tiếp cận tới một kiến thức khá là quan trọng mà mỗi người học lập trình C++ đều phải biết và áp dụng nó. Đó chính là Template.

Bạn đang xem: Template c++ là gì, sử dụng template trong c++ thế nào (phần 1)

1. Template trong C++ là gì?

Template(khuôn mẫu) là một từ khóa trong C++, và là một kiểu dữ liệu trừu tượng tổng quát hóa cho các kiểu dữ liệu int, float, double, bool…Template trong C++ có 2 loại đó là function template & class template.Template giúp người lập trình định nghĩa tổng quát cho hàm và lớp thay vì phải nạp chồng (overloading) cho từng hàm hay phương thức với những kiểu dữ liệu khác nhau.

2. Cách sử dụng template đối với hàm

Cú pháp khai báo hàm khuôn mẫu

Template(khuôn mẫu) là một từ khóa trong C++, và là một kiểu dữ liệu trừu tượng tổng quát hóa cho các kiểu dữ liệu int, float, double, bool…Template trong C++ có 2 loại đó là function template & class template.Template giúp người lập trình định nghĩa tổng quát cho hàm và lớp thay vì phải nạp chồng (overloading) cho từng hàm hay phương thức với những kiểu dữ liệu khác nhau.Cú pháp khai báo hàm khuôn mẫu

template T someFunction(T arg1, …){ …}

Tại sao chúng ta phải dùng template nhỉ?

Các bạn thử xem ví dụ đối với hàm swapVal() dưới đây rồi tự rút ra nhận xét cho riêng mình nhé.

void swapVal(int &a , int &b){ int temp; temp = a; a = b; b = temp;}

Hàm swapVal(int &a , int &b) chỉ áp dụng cho 2 biến kiểu int, do đó muốn đổi 2 biến với các kiểu dữ liệu double, char, string… chúng ta phảioverloading nó thêm 1 lần nữa

void swapVal(double &a , double &b){ double temp; temp = a; a = b; b = temp;}

Qua ví dụ trên chúng ta có thể thấy việc nạp chồng liên tục các hàm nhiều lần như vậy mất nhiều thời và bộ nhớ của máy tính, để tối ưu việc nạp chồng chúng ta sẽ xử lí chúng bằng cách viết một hàm khuôn mẫu swapVal như sau:

template void swapVal(val &a , val &b){ val temp; temp = a; a = b; b = temp;}

Chúng ta thử chạy xem sao nhé:

#include using namespace std;template void swapVal(val &a , val &b){ val temp; temp = a; a = b; b = temp;}int main(){ int intX = 2, intY = 3; double doubleX = 1.2, doubleY = 3.1; string str1 = “Code”, str2 = “Learn”; //gọi hàm swapVal() đối với 2 số nguyên swapVal(intX, intY); cout Sau khi chạy chương trình sẽ có kết quả:

*

Qua ví dụ trên chúng ta có thể thấy kiểu dữ liệu của biến định nghĩa chính xác được quyết định ở thời điểm chạy, và chương trình ngắn gọn hơn rất nhiều so với nạp chồng từng hàm swapVal()

Giải thích:

Tiền tố khuôn mẫutemplate Ở đây class là kiểu hoặc sự phân lớp nên nó không phải là từ class chúng ta hay thấy ở trong lập trình hướng đối tượng.C++ cho phép sử dụng từ khóa “typename” ở vị trí từ khóa class, tuy nhiên chúng ta nên sử dụng từ khóa class trong mọi trường hợp.(Trong phần sau mình sẽ nói rõ khi nào dùng typename , khi nào dùng class)Trong thân định nghĩa hàm, val được sử dụng giống như một kiểu bất kì trùng với kiểu dữ liệu truyền vào.Từvallà tên trượng trưng cho class nên có thể được thay thế bằng bất kì từ nào khác chúng ta muốn.Định nghĩa khuôn mẫu hàm:Khuôn mẫu hàm swapVal()là một tập hợp các định nghĩa.Khi chúng ta chạy chương trình với đối số truyền vào hàm swapVal() là kiểu int thì khi này trình biên dịch sẽ phát sinh định nghĩa một hàm swapVal(int& a, int& b) mà không phát sinh ra các định nghĩa cho các đối số kiểu float , double hay string. Do vậy chúng ta có thể kết luận được rằng trình biên dịch chỉ phát sinh các định nghĩa khi được yêu cầu với điều kiện ta đã định nghĩa cho tất cả các kiểu.Qua đó ta có thể thấy ưu điểm vượt trội của template trong C++ là chúng ta viết một hàm định nghĩa nó sẽ làm việc cho tất cả các kiểu có thể có.Gọi khuôn mẫu hàmXét lời gọi hàm swapVal(intX,intY) bộ biên dịch C++ sử dụng khuôn mẫu để khởi tạo định nghĩa hàm cho hai tham số int và tương tự với tất cả các kiểu khác.

Xem thêm:

Tiền tố khuôn mẫutemplate Ở đây class là kiểu hoặc sự phân lớp nên nó không phải là từ class chúng ta hay thấy ở trong lập trình hướng đối tượng.C++ cho phép sử dụng từ khóa “typename” ở vị trí từ khóa class, tuy nhiên chúng ta nên sử dụng từ khóa class trong mọi trường hợp.(Trong phần sau mình sẽ nói rõ khi nào dùng typename , khi nào dùng class)Trong thân định nghĩa hàm, val được sử dụng giống như một kiểu bất kì trùng với kiểu dữ liệu truyền vào.Từvallà tên trượng trưng cho class nên có thể được thay thế bằng bất kì từ nào khác chúng ta muốn.Định nghĩa khuôn mẫu hàm:Khuôn mẫu hàm swapVal()là một tập hợp các định nghĩa.Khi chúng ta chạy chương trình với đối số truyền vào hàm swapVal() là kiểu int thì khi này trình biên dịch sẽ phát sinh định nghĩa một hàm swapVal(int& a, int& b) mà không phát sinh ra các định nghĩa cho các đối số kiểu float , double hay string. Do vậy chúng ta có thể kết luận được rằng trình biên dịch chỉ phát sinh các định nghĩa khi được yêu cầu với điều kiện ta đã định nghĩa cho tất cả các kiểu.Qua đó ta có thể thấy ưu điểm vượt trội của template trong C++ là chúng ta viết một hàm định nghĩa nó sẽ làm việc cho tất cả các kiểu có thể có.Gọi khuôn mẫu hàmXét lời gọi hàm swapVal(intX,intY) bộ biên dịch C++ sử dụng khuôn mẫu để khởi tạo định nghĩa hàm cho hai tham số int và tương tự với tất cả các kiểu khác.Xem thêm: Nghĩa Của Từ White Collar Worker Là Gì ? Nhân Viên Cổ Cồn Xanh

Một số lưu ý khi viếthàmtemplate:

Một template , temp chỉ có tác vụ định nghĩa cho 1 kiểu dữ liệu duy nhất do đó chúng ta không thể gán 1 biến kiểu int và double cho cùng 1 kiểu dữ liệu temptrong cùng một thời điểm.

Một template , temp chỉ có tác vụ định nghĩa cho 1 kiểu dữ liệu duy nhất do đó chúng ta không thể gán 1 biến kiểu int và double cho cùng 1 kiểu dữ liệu temptrong cùng một thời điểm.

Ví dụ:

#include using namespace std;template void sum(temp intVal , temp doubleVal) {coutChương trình sẽ báo lỗi như ảnh dưới

Để giải quyết vấn đề đó thì ta khai báo thêm một kiểu dữ liệu tổng quát vào như sau:

#include using namespace std;template void sum(temp intVal , temp1 doubleVal) {coutKhi chạy chương trình ta sẽ nhận được kết quả là 2.1, từ đây chúng ta có thể thấy rằngkhi ta muốn dùng bao nhiêu kiểu dữ liệu tổng quát thì khai báo bấy nhiêu.

Khi lấy temp làm kiểu dữ liệu trả về cho hàm, chúng cũng chỉ nhận kiểu dữ liệu của biến trả về theo kiểu dữ liệu của biến truyền vào mà không trả về một kiểu dữ liệu khác được

Khi lấy temp làm kiểu dữ liệu trả về cho hàm, chúng cũng chỉ nhận kiểu dữ liệu của biến trả về theo kiểu dữ liệu của biến truyền vào mà không trả về một kiểu dữ liệu khác được

#include using namespace std;template temp thuong(temp x1, temp x2){return (x1*1.0)/x2;}int main(){int x1 = 1 , x2 = 2;coutKết quả của chương trình ra 0 bởi vì temp sẽ nhận kiểu dữ liệu theo biến x1 , x2 đã được định nghĩa trước kiểu int vì thế giá trị trả về là 0 mà không thể trả về kết quả như mong muốn là 0.5, do khi trình biên dịch chạy nó sẽ tự động nhận kiểu dữ liệu của biến truyền vào. Vì vậy khi viết khuôn hàm mẫu chúng ta nên cẩn thận trong trường hợp trả về kết quả như này nhé.

Tạm Kết

Vậy là chúng ta đã tìm hiểu được một phần của template trong C++, cụ thể là function template. Qua bài viết này mình mong các bạn nhớ được cú pháp, các dùng của function template và những lưu ý khi viết hàm template.

Mình mong các có thể làm được bài tập nhỏ mình đưa ra sau đây: “Viết một hàm có sử dụng khuôn mẫu nhập vào một mảng có các giá trị có kiểu tùy ý và trả về giá trị có số lần xuất hiện nhiều nhất trong mảng.” (bạn nào cần code thì comment gmail nhé)

Mong các bạn rate và comment ý kiến ở phía dưới để những bài sau mình ra tốt hơn. Cảm ơn các bạn hẹn gặp lại các bạn vào phần tiếp theo Class Template.

Chuyên mục:

Chuyên mục: Tài liệu