Sự cần thiết của khuôn mẫu lambda được giới thiệu trong C ++ 20 khi C ++ 14 đã có lambda chung là gì?


99

đã giới thiệu các lambdas chung để có thể viết như sau:

auto func = [](auto a, auto b){
    return a + b;
};
auto Foo = func(2, 5);
auto Bar = func("hello", "world");

Rất rõ ràng rằng lambda chung này funchoạt động giống như một hàm được tạo mẫu funcsẽ hoạt động.

Tại sao ủy ban C ++ quyết định thêm cú pháp mẫu cho lamda chung?


5
Điều gì sẽ xảy ra nếu bạn cần sử dụng một kiểu mẫu khác với các đối số hoặc kiểu trả về? Và nếu nó cần bên trong cơ thể thì sao?
Một số lập trình viên anh chàng

Tôi đã được cho biết đây là một trường hợp sử dụng thú vị.
Max Langhof

Câu trả lời:


115

Các lambdas chung trong C ++ 14 là một cách rất hay để tạo một functor có dạng operator ()như sau:

template <class T, class U>
auto operator()(T t, U u) const;

Nhưng không phải như thế này:

template <class T>
auto operator()(T t1, T t2) const; // Same type please

Cũng không phải như thế này:

template <class T, std::size_t N>
auto operator()(std::array<T, N> const &) const; // Only `std::array` please

Cũng không phải như thế này (mặc dù điều này hơi khó sử dụng):

template <class T>
auto operator()() const; // No deduction

C ++ 14 lambdas là tốt, nhưng C ++ 20 cho phép chúng tôi thực hiện những trường hợp này mà không gặp rắc rối.


2
Đẹp và ngắn gọn. Chỉ cần thêm điều này: Có thể giải quyết vấn đề đầu tiên (cùng kiểu) (auto a, decltype(a) b)trong C ++ 14.
Sebastian Mach

13
@SebastianMach gần như. Với giải pháp đó blà không suy luận và đối số của nó sẽ được chuyển đổi ngầm định thành kiểu athay thế.
Quentin

32

Vì bạn có thể sử dụng lambdas được tạo mẫu trong C ++ 20, bạn có thể hạn chế các loại của mình theo cách dễ dàng hơn so với biểu thức SFINAE:

auto lambda = []<typename T>(std::vector<T> t){};

Lambda này sẽ chỉ hoạt động với các loại vector.


8
Làm thế nào có constevalliên quan đến cú pháp mới? Nó tuyệt vời và tất cả, nhưng tôi không nhận được sự liên quan.
người kể chuyện - Unslander Monica

Đó là thêm một thông tin về những gì C ++ 20 add để biểu thức lambda hơn một câu trả lời cho câu hỏi
Antoine Morrier

24

Các đề nghị đã được chấp nhận vào C ++ 20 có một phần động lực kéo dài, với các ví dụ. Tiền đề của nó là:

Có một vài lý do chính khiến cú pháp hiện tại để xác định lambdas chung chung được tác giả cho là không đủ. Ý chính của nó là một số thứ có thể được thực hiện dễ dàng với các mẫu hàm thông thường yêu cầu nhảy vòng đáng kể phải được thực hiện với lambdas chung chung, hoặc hoàn toàn không thể thực hiện được. cũng như các mẫu chức năng bình thường.

Sau đó là một số ví dụ.


21

"Cú pháp mẫu quen thuộc" mới cho lambdas được giới thiệu trong C ++ 20 làm cho các cấu trúc như  for_types và  for_range khả thi và dễ đọc hơn so với các lựa chọn thay thế C ++ 17.

(nguồn: lặp thời gian biên dịch với C ++ 20 lambdas )

Một điều thú vị khác có thể được thực hiện trên lambdas chung C ++ 14 và C ++ 17 là gọi trực tiếp operator()  bằng cách truyền rõ ràng tham số mẫu:

C ++ 14:

   auto l = [](auto){ };
   l.template operator()<int>(0);

C ++ 20:

  auto l = []<typename T>(){ };
  l.template operator()<int>();

Ví dụ C ++ 14 ở trên khá vô dụng: không có cách nào đề cập đến kiểu được cung cấp  operator() trong phần thân của lambda mà không đặt tên cho đối số và sử dụng decltype . Ngoài ra, chúng tôi buộc phải vượt qua một đối số mặc dù chúng tôi có thể không cần nó.

Ví dụ C ++ 20 cho thấy T có thể dễ dàng truy cập trong phần thân của lambda và lambda nullary bây giờ có thể được tạo mẫu tùy ý. Điều này sẽ rất hữu ích cho việc triển khai các cấu trúc thời gian biên dịch nói trên

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.