2015-12-31 23 views
9

Trong this article, đoạn code sau được trình bày:loại trình biên dịch-suy luận cho lambdas generic

std::vector<int> ivec = { 1, 2, 3, 4}; 
std::vector<std::string> svec = { "red", "green", "blue" }; 
auto adder = [](auto op1, auto op2){ return op1 + op2; }; 
std::cout << "int result : " 
      << std::accumulate(ivec.begin(), 
          ivec.end(), 
          0, 
          adder) 
      << "\n"; 
std::cout << "string result : " 
      << std::accumulate(svec.begin(), 
          svec.end(), 
          std::string(""), 
          adder) 
      << "\n"; 

Nếu tôi hiểu đúng, trình biên dịch sẽ tạo ra một lớp học nội nhiều như thế này:

template<class T> 
class _lambda 
{ 
    public: 
    T operator()(T lhs, T rhs) { return lhs + rhs; } 
}; 

Nhưng những gì tôi không hiểu là, trong phần này của mã, adder dường như có hai loại cùng một lúc: _lambda<int>_lambda<string>. Sao có thể như thế được?

Trả lời

8

Theo 5.1.2/p5 Lambda biểu thức tiêu chuẩn [expr.prim.lambda]:

Đối với một lambda chung chung, kiểu đóng cửa có một công inline chức năng thành viên điều hành cuộc gọi mẫu (14,5. 2) có mẫu tham số-danh sách bao gồm một kiểu mẫu tham số được phát minh cho mỗi lần xuất hiện của tự động trong mệnh đề khai báo tham số lambda, theo thứ tự xuất hiện .

Do đó, những gì đang thực sự tạo ra là:

class _lambda { 
public: 
    template<typename T1, typename T2> 
    auto operator()(T1 lhs, T2 rhs) const { return lhs + rhs; } 
}; 
+0

Tương tự như vậy, nếu các đối số giống như'auto && lhs'. sau đó nó tạo ra 'T && lhs' .. và cứ thế. – Nawaz

8

Không. Nó tạo ra một cái gì đó như thế này:

class _lambda { 
public: 
    template<class T1, class T2> 
    auto operator()(T1 lhs, T2 rhs) const { return lhs + rhs; } 
}; 

Lớp học không được tô điểm. operator() là.

+0

ah vâng có ý nghĩa! cảm ơn – qdii

+0

Tương tự, nếu các đối số giống như'auto && lhs'. sau đó nó tạo ra 'T && lhs' .. và cứ thế. – Nawaz

+1

@Nawaz trong ví dụ của mình, chúng không phải là – bolov

1

Như một vấn đề của thực tế, trình biên dịch sẽ tạo ra một lớp học như thế này:

class _lambda { 
public: 
    template<class T, class U> 
    auto operator()(T lhs, U rhs) const { return lhs + rhs; } 
}; 

Hai đối số là không nhất thiết phải cùng loại, điều kiện duy nhất là sự tồn tại của operator+() với các loại đối số liên quan.

Xem bản trình diễn trên coliru.

+0

Tôi quá chậm: ( – YSC

+0

Tương tự như vậy, nếu các đối số giống như'auto && lhs'. Thì nó sẽ tạo 'T && lhs' .. v.v. – Nawaz

Các vấn đề liên quan