Từ khóa tự động C ++. Tại sao nó là ma thuật?


144

Từ tất cả các tài liệu tôi đã sử dụng để tìm hiểu C ++, autoluôn là một công cụ xác định thời lượng lưu trữ kỳ lạ không phục vụ cho bất kỳ mục đích nào. Nhưng chỉ gần đây, tôi đã gặp mã sử dụng nó như là một loại tên trong chính nó. Vì tò mò tôi đã thử nó, và nó giả định loại bất cứ điều gì tôi xảy ra để gán cho nó!

Đột nhiên, các trình lặp STL và, tốt, mọi thứ sử dụng các mẫu đều dễ viết hơn 10 lần. Cảm giác như tôi đang sử dụng ngôn ngữ 'vui vẻ' như Python.

Trường hợp này đã có từ khóa này cả đời tôi? Bạn sẽ thực hiện ước mơ của mình bằng cách nói nó độc quyền cho studio hình ảnh hay không di động?


18
nó không thể. ma thuật. Nó là mới ( oh noes, thật là một sự chơi chữ tồi ). Bây giờ async là tương lai ( thở hổn hển )
sehe

2
Dưới đây là tài liệu tham khảo về từ khóa tự động en.cppreference.com/w/cpp/lingu/auto
andyqee

Câu trả lời:


149

auto là một từ khóa mà C ++ "thừa hưởng" từ C đã tồn tại gần như mãi mãi, nhưng hầu như không bao giờ được sử dụng bởi vì chỉ có hai điều kiện có thể: hoặc nó không được phép, hoặc nếu không thì nó được mặc định.

Việc sử dụng autođể chỉ một loại suy diễn là mới với C ++ 11.

Đồng thời, auto x = initializersuy ra kiểu xtừ loại initializergiống như cách khấu trừ kiểu mẫu cho các mẫu hàm. Hãy xem xét một mẫu hàm như thế này:

template<class T>
int whatever(T t) { 
    // point A
};

Tại điểm A, một loại đã được chỉ định Tdựa trên giá trị được truyền cho tham số whatever. Khi bạn thực hiện auto x = initializer;, khấu trừ cùng loại được sử dụng để xác định loại cho loại xtừ initializerđược sử dụng để khởi tạo nó.

Điều này có nghĩa là hầu hết các cơ chế khấu trừ kiểu mà trình biên dịch cần triển khai autođã có mặt và được sử dụng cho các mẫu trên bất kỳ trình biên dịch nào thậm chí đã cố gắng thực hiện C ++ 98/03. Như vậy, việc thêm hỗ trợ autorõ ràng khá dễ dàng đối với tất cả các nhóm trình biên dịch - nó được thêm vào khá nhanh và dường như cũng có một vài lỗi liên quan đến nó.

Khi câu trả lời này ban đầu được viết (vào năm 2011, trước khi mực khô trên chuẩn C ++ 11) autođã khá di động. Ngày nay, nó hoàn toàn di động trong số tất cả các trình biên dịch chính. Những lý do rõ ràng duy nhất để tránh nó là nếu bạn cần viết mã tương thích với trình biên dịch C hoặc bạn có nhu cầu cụ thể để nhắm mục tiêu một số trình biên dịch thích hợp mà bạn biết không hỗ trợ nó (ví dụ: một vài người vẫn viết mã đối với MS-DOS sử dụng trình biên dịch từ Borland, Watcom, v.v., chưa thấy sự nâng cấp đáng kể nào trong nhiều thập kỷ). Nếu bạn đang sử dụng một phiên bản hợp lý hiện tại của bất kỳ trình biên dịch chính nào, thì không có lý do gì để tránh nó cả.


23

Nó chỉ là một từ khóa thường vô dụng và cung cấp cho nó một chức năng mới tốt hơn. Đó là tiêu chuẩn trong C ++ 11 và hầu hết các trình biên dịch C ++ có hỗ trợ C ++ 11 thậm chí sẽ hỗ trợ nó.


Oh! Aha, không bao giờ nghĩ về ngôn ngữ C ++ là một thứ có thể thay đổi. Tôi sẽ phải tìm kiếm những gì họ đã thêm vào C ++ 11 này, tôi đã nghe một chút về C ++ 0x nhưng không bao giờ đào quá sâu vào nó.
Anne Quinn

7
@Clairvoire C ++ 0x là tên tạm thời. Nó đã được xuất bản trong tháng này, và do đó trở thành C ++ 11.
R. Martinho Fernandes

13

Đối với các biến, chỉ định rằng loại biến đang được khai báo sẽ được tự động suy ra từ trình khởi tạo của nó. Đối với các hàm, chỉ định rằng kiểu trả về là kiểu trả về theo sau hoặc sẽ được suy ra từ các câu lệnh trả về của nó (kể từ C ++ 14).

Cú pháp

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

Giải trình

1) Khi khai báo các biến trong phạm vi khối, trong phạm vi không gian tên, trong các câu lệnh khởi tạo cho các vòng lặp, v.v., từ khóa tự động có thể được sử dụng làm công cụ xác định kiểu. Khi loại trình khởi tạo đã được xác định, trình biên dịch sẽ xác định loại sẽ thay thế từ khóa tự động bằng cách sử dụng các quy tắc để khấu trừ đối số mẫu từ một lệnh gọi hàm (xem khấu trừ đối số mẫu # Các bối cảnh khác để biết chi tiết). Tự động từ khóa có thể được kèm theo các sửa đổi, chẳng hạn như const hoặc &, sẽ tham gia vào loại trừ. Ví dụ, đã cho const auto& i = expr;, loại i chính xác là loại đối số u trong một mẫu tưởng tượng template<class U> void f(const U& u)nếu hàm gọif(expr)đã được biên soạn. Do đó, auto && có thể được suy ra dưới dạng tham chiếu giá trị hoặc tham chiếu giá trị theo trình khởi tạo, được sử dụng trong vòng lặp dựa trên phạm vi. Nếu tự động được sử dụng để khai báo nhiều biến, các loại suy ra phải khớp. Ví dụ, khai báo auto i = 0, d = 0.0;không đúng định dạng, trong khi khai báo auto i = 0, *p = &i;được định dạng tốt và tự động được suy ra là int.

2) Trong một khai báo hàm sử dụng cú pháp kiểu trả về theo sau, từ khóa tự động không thực hiện phát hiện loại tự động. Nó chỉ phục vụ như là một phần của cú pháp.

3) Trong một khai báo hàm không sử dụng cú pháp kiểu trả về theo sau, từ khóa tự động chỉ ra rằng kiểu trả về sẽ được suy ra từ toán hạng của câu lệnh trả về của nó bằng cách sử dụng các quy tắc để khấu trừ đối số khuôn mẫu.

4) Nếu loại khai báo của biến là dectype (auto), từ khóa auto được thay thế bằng biểu thức (hoặc danh sách biểu thức) của bộ khởi tạo và loại thực tế được suy luận bằng cách sử dụng quy tắc cho dectype.

5) Nếu loại trả về của hàm được khai báo là dectype (auto), từ khóa auto được thay thế bằng toán hạng của câu lệnh return và loại trả về thực tế được suy luận bằng cách sử dụng các quy tắc cho dectype.

6) Trình xác định tên lồng nhau của biểu mẫu tự động :: là một trình giữ chỗ được thay thế bằng một loại hoặc kiểu liệt kê theo các quy tắc để khấu trừ giữ chỗ loại bị ràng buộc.

7) Một khai báo tham số trong biểu thức lambda. (kể từ C ++ 14) Một khai báo tham số hàm. (khái niệm TS)

Ghi chú Cho đến C ++ 11, auto có ngữ nghĩa của bộ xác định thời lượng lưu trữ. Trộn các biến và hàm tự động trong một khai báo, như trong auto f() -> int, i = 0;không được phép.

Để biết thêm thông tin: http://en.cppreference.com/w/cpp/lingu/auto


11

Chức năng này đã không có ở đó cả đời bạn. Nó được hỗ trợ trong Visual Studio kể từ phiên bản 2010. Đây là một tính năng mới của C ++ 11, vì vậy nó không dành riêng cho Visual Studio và sẽ / sẽ có thể mang theo được. Hầu hết các trình biên dịch đều hỗ trợ nó.


3

Nó không đi đâu cả ... đó là một tính năng C ++ tiêu chuẩn mới trong việc triển khai C ++ 11. Điều đó đang được nói, trong khi đó là một công cụ tuyệt vời để đơn giản hóa các khai báo đối tượng cũng như làm sạch cú pháp cho các mô hình cuộc gọi nhất định (nghĩa là các vòng lặp dựa trên phạm vi), không sử dụng / lạm dụng nó quá mức :-)


3

Từ khóa tự động xác định rằng loại biến đang được khai báo sẽ được tự động khấu trừ khỏi bộ khởi tạo. Trong trường hợp các hàm, nếu kiểu trả về của chúng là tự động thì điều đó sẽ được đánh giá bằng biểu thức kiểu trả về khi chạy.

Nó có thể rất hữu ích khi chúng ta phải sử dụng iterator. Ví dụ, đối với mã dưới đây, chúng ta chỉ cần sử dụng "tự động" thay vì viết toàn bộ cú pháp lặp.

int main() 
{ 

// Initialize set 
set<int> s; 

s.insert(1); 
s.insert(4); 
s.insert(2); 
s.insert(5); 
s.insert(3); 

// iterator pointing to 
// position where 2 is 
auto pos = s.find(3); 

// prints the set elements 
cout << "The set elements after 3 are: "; 
for (auto it = pos; it != s.end(); it++) 
    cout << *it << " "; 

return 0; 
}

Đây là cách chúng ta có thể sử dụng từ khóa "tự động"


0

Điều kỳ diệu là khả năng giảm việc phải viết mã cho mọi Loại biến được truyền vào các chức năng cụ thể. Hãy xem xét một hàm print () tương tự Python trong cơ sở C của nó.

#include <iostream>
#include <string>
#include <array>

using namespace std;

void print(auto arg) {
     cout<<arg<<" ";
}

int main()
{
  string f = "String";//tok assigned
  int x = 998;
  double a = 4.785;
  string b = "C++ Auto !";
//In an opt-code ASCII token stream would be iterated from tok's as:
  print(a);
  print(b);
  print(x);
  print(f);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.