2015-02-19 24 views
7

tôi tìm thấy những câu hỏi tương tự Lambda expressions as class template parametersHow to use a lambda expression as a template parameter?, nhưng ngay cả với các câu trả lời có sẵn tôi didnt có được tại sao đoạn code sau đây không hoạt động (g ++ 4.8.2 và g ++ - 4,9):Lambda như mẫu tham số

auto GoLess = [](int a,int b) -> bool 
{ 
     return a < b; 
}; 


template<typename Order> 
struct foo 
{ 
     int val; 
     bool operator<(const foo& other) 
     { 
       return Order(val, other.val); 
     } 
}; 

typedef foo<decltype(GoLess)> foo_t; 

int main() 
{ 
     foo_t a,b; 
     bool r = a < b; 
} 

sản lượng biên dịch là:

test.cpp: In instantiation of ‘bool foo<Order>::operator<(const foo<Order>&) [with Order = <lambda(int, int)>]’: 
test.cpp:26:15: required from here 
test.cpp:17:30: error: no matching function for call to ‘<lambda(int, int)>::__lambda0(int&, const int&)’ 
    return Order(val, other.val); 
          ^
test.cpp:17:30: note: candidates are: 
test.cpp:5:16: note: constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&) 
auto GoLess = [](int a,int b) -> bool 
       ^
test.cpp:5:16: note: candidate expects 1 argument, 2 provided 
test.cpp:5:16: note: constexpr<lambda(int, int)>::<lambda>(<lambda(int, int)>&&) 
test.cpp:5:16: note: candidate expects 1 argument, 2 provided 

nên không làm việc mã này? Đọc từ những chủ đề khác trong sự hiểu biết của tôi mã này nên biên dịch, nhưng không phải là.

Thanks a lot

Phụ Lục:

Để làm rõ một chút, ở trên của các câu hỏi trên KennyTM viết đoạn mã sau:

auto comp = [](const A& lhs, const A& rhs) -> bool { return lhs.x < rhs.x; }; 
auto SetOfA = std::set <A, decltype(comp)> (comp); 

nào nên làm việc, đối số thứ hai để std :: set là một 'comparator' mà trong trường hợp này là lambda, trong code của tôi tôi đang cố gắng làm tương tự hoặc ít nhất tôi nghĩ rằng tôi đang làm như vậy, nhưng mã của tôi không hoạt động. Cái gì tôi thiếu trong mã của tôi?

Xin lưu ý cũng từ Xéo trong Lambda expressions as class template parameters

auto my_comp = [](const std::string& left, const std::string& right) -> bool { 
    // whatever 
} 

typedef std::unordered_map< 
    std::string, 
    std::string, 
    std::hash<std::string>, 
    decltype(my_comp) 
    > map_type; 

Một lần nữa điều này sẽ làm việc. Đâu là lỗi của tôi?

Cảm ơn

+0

Xin giải thích lý do tại sao bạn nghĩ rằng mã nên biên dịch. (Nó có thể ảnh hưởng đến câu trả lời.) –

+0

'const'. Kiểm tra 'const's. – John

Trả lời

9

Như trình biên dịch được helpfully nói cho bạn, vấn đề là với dòng này:

return Order(val, other.val); 

Kể từ Order là một loại (và không một chức năng), đó là kêu gọi của tự hai -giá xây dựng. Nhưng nó không có.

Cú pháp đúng cho cách gọi một lớp chức năng là:

return Order()(val, other.val); 

Tuy nhiên, đó sẽ không làm việc hoặc vì các lớp tạo cho lambda có một constructor mặc định xóa.

Tóm lại, bạn cần khởi tạo lớp của mình với (chỉ) thể hiện của lambda.

Dưới đây là một cách có thể để tiến hành:

template<typename Order> 
struct foo { 
    foo(Order compare) : compare_(compare) {} 
    bool operator<(const foo& other) { 
     return compare_(val, other.val); 
    } 
    int val; 
    Order compare_; 
}; 

/* In practice, you'll want to template a parameter pack 
* for the other arguments to the constructor, since those are likely. 
* Also, you might want to use std::forward. 
*/ 
template<typename Order> 
foo<Order> foomaker(Order order) { 
    return foo<Order>(order); 
} 

int main() { 
    auto GoLess = [](int a,int b) -> bool 
     { 
      return a < b; 
     }; 

    auto a = foomaker(GoLess); 
    auto b = foomaker(GoLess); 
    bool r = a < b; 
    return r; 
} 
+1

Cụ thể, ngoài 'decltype (GoLess)', 'GoLess' cần được cung cấp và truyền cho hàm tạo' foo'. – EyasSH

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