Auto được bắt đầu sử dụng từ C++11, nó giúp lập trình viên tối giản việc khai báo biến với ý nghĩa “tự động” suy luận kiểu dữ liệu của biến và tất nhiên công việc đó thuộc về compiler. Giống như trường hợp của template, compiler suy luận kiểu dữ liệu của biến theo 3 trường hợp và những quy tắc hoàn toàn tương tự. (nếu bạn chưa đọc về suy luận kiểu dữ liệu trong template, vui lòng tham khảo bài viết trước đó: link)
Suy luận kiểu dữ liệu với auto

Sử dụng auto thay thế cho khai báo tường minh
Rõ ràng việc sử dụng auto gây ra sự khó chịu nhất định đối với người đọc code bởi lẽ việc khai báo biến không tường minh khiến chúng ta cảm thấy nhập nhằng trong việc xác định kiểu dữ liệu của biến. Tuy vậy, sự không tường minh đó có thể trở thành sự linh hoạt trong một số trường hợp.
Khi bạn đang không biết đang làm việc trên kiểu dữ liệu nào
Chắc chắn rồi, điều đó chỉ có thể xảy ra với sự có mặt của template và auto, 2 thủ phạm khiến cho mọi thứ trở nên mờ ảo. Giả sử ông sếp của bạn muốn tạo ra một hàm swap với tham số truyền vào kiểu con trỏ kiểu như sau:
template<typename Ptr>
void swap(Ptr a, Ptr b){
}
Rồi sếp bạn đi uống trà đá, ông ấy giao cho bạn phải implement hàm trên, thuật toán quá đơn giản, bạn tự tin viết code. Thông thường chúng ta sẽ lưu một biến temp trước khi thực hiện hoán đổi giá trị của a và b, nhưng để làm điều đó chúng ta phải khai báo temp như thế nào? Kiểu dữ liệu khi sử dụng template được suy luận bởi trình biên dịch, cho nên nếu bạn không biết khai báo temp với kiểu dữ liệu nào, hãy tiếp tục để trình biên dịch suy luận điều đó:
template<typename Ptr>
void swap(Ptr a, Ptr b){
auto temp = *a;
*a = *b;
*b = temp;
}
Thực lòng cũng khó mà có cách nào khác ngoài cách trên, bây giờ bạn có thể yên tâm chờ ông sếp đi uống trà về.
Khi sử dụng lambda
Thuật ngữ lambda được bắt đầu sử dụng từ C++11, là hàm không có tên. Nếu bạn chưa quen với thuật ngữ này, vùi lòng tham khảo tài liệu về lambda.
Vậy kiểu dữ liệu của lambda là gì và làm thế nào để khai báo nó? Lambda không có cách khai báo thông thường như các kiểu dữ liệu nguyên thủy, và cũng chẳng có định nghĩa nào về kiểu dữ liệu của lambda. Chúng ta thường sử dụng auto để khai báo lambda:
auto sum = [](int x, int y){return x+y};
Tất nhiên, chúng ta có những cách khác để khai báo lambda:
Sử dụng con trỏ hàm:
int(*sum_2)(int, int) = [](int x, int y){return x+y}; //cách 2
Sử dụng std::function:
std::function<int(int, int)> sum_3 = [](int x, int y){return x+y}; //cách 3
Tuy nhiên, nếu so sánh với việc sử dụng auto, chúng tồn tại 2 yếu điểm:
- Thứ nhất, rõ ràng cả cách 2 và 3 dài dòng hơn khi cần phải khai báo chi tiết chữ ký hàm
- Thứ hai, việc khai báo như trên sẽ tốn nhiều bộ nhớ hơn, đặc biệt là cách thứ 3 khi sum_3 thực chất là đối tượng của class std::function. Ngoài việc phải lưu địa chỉ của hàm lambda, nó còn bao gồm các trường khác trong class. Việc thực hiện lời gọi hàm thông qua sum_3 cũng lâu hơn so với sum do cơ chế của class std::function.
Khi bạn định sử dụng kiểu dữ liệu đường tắt.
Kiểu dữ liệu đường tắt là gì? Giả sử ta có một vector v như sau:
std::vector<int> v;
Bây giờ ta muốn lấy kích thước của vector v thông qua phương thức v.size(), phương thức này trả về giá trị kiểu std::vector<int>::size_type, tuy nhiên nhiều người thường ngầm hiểu nó tương đương với kiểu unsigned, nên để đơn giản họ thường chọn cách đi đường tắt:
unsigned size = v.size();
Với hệ điều hành 32 bit, việc sử dụng std::vector<int>::size_type và unsigned là như nhau. Tuy nhiên, nếu chuyển sang môi trường 64bit, kích thước của std::vector<int>::size_type là 8 bytes, trong khi đó kích thước của unsigned vẫn là 4 bytes, theo đó đoạn code trên không còn đúng đắn nữa.
Để đơn giản trong trường hợp này, chúng ta nên sử dụng auto, vừa gọn nhẹ lại đảm bảo tính đúng đắn khi thực thi trên các kiến trúc OS khác nhau.
auto size = v.size();
Tất nhiên không phải trường hợp nào chúng ta cũng đè auto ra sử dụng, ở phần tiếp theo mình sẽ thảo luận các trường hợp không nên thay thế auto cho khai báo tường minh.
Tạm kết thúc phần 1 ở đây, như thường lê, nếu có bất kỳ thắc măc hay trao đổi gì, hãy comment phía dưới nhé.