2015-01-08 23 views
9

Các chương trình sau đây là bất hợp pháp, và tôi muốn hiểu lý do tại sao:Tại sao tôi không thể vượt qua một lambda đến chức năng này trong đó có một chức năng :: std?

#include <functional> 
#include <iostream> 

template<typename Result, typename Arg> 
void deduce(std::function<Result(Arg)> f) 
{ 
    std::cout << "Result: " << typeid(Result).name() << std::endl; 
    std::cout << "Arg: " << typeid(Arg).name() << std::endl; 
} 


int main() 
{ 
    auto f = [](int x) 
    { 
    return x + 1; 
    }; 

    deduce(f); 

    return 0; 
} 

clang 's đầu ra:

$ clang -std=c++11 test.cpp 
test.cpp:48:3: error: no matching function for call to 'deduce' 
    deduce(f); 
    ^~~~~~ 
test.cpp:26:6: note: candidate template ignored: could not match 'function<type-parameter-0-1 (type-parameter-0-0)>' against '<lambda at test.cpp:34:13>' 
void deduce(std::function<T2(T1)> f) 
    ^
1 error generated. 

Nó có vẻ như tôi phải có khả năng chuyển đổi lambda của tôi vào std::function đã nhận được deduce. Tại sao không thể cho trình biên dịch áp dụng một chuyển đổi thích hợp trong trường hợp này?

Trả lời

5

Vấn đề là trong khi một lambda mà phải mất một int và trả về một int có thể chuyển thành một std::function<int(int)>, kiểu của nó là khôngstd::function<int(int)> nhưng một loại thực hiện xác định tùy ý tôi nghĩ.

Bạn có thể giải quyết vấn đề này bằng cách nói cho trình biên dịch biết loại bạn muốn. Sau đó, chuyển đổi sẽ diễn ra như mong đợi.

auto f = [](int x){ return x + 1; }; 
deduce<int, int>(f); // now ok 

Hoặc, hãy rõ ràng trên loại tĩnh là f.

std::function<int(int)> f = [](int x){ return x + 1; }; 
deduce(f); // now also ok 
+0

Cảm ơn. Tôi hiểu các loại không giống nhau, nhưng tôi đang cố gắng hiểu tại sao trình biên dịch không thể áp dụng một chuyển đổi thích hợp ở đây. –

+2

Vấn đề không phải là việc chuyển đổi giá trị đối số mà là việc khấu trừ các tham số mẫu. Một khi chúng được biết (như trong đoạn đầu tiên tôi đưa ra), việc chuyển đổi là tốt. Tôi sẽ thử xem tôi có thể tra cứu các quy tắc chính xác có hiệu lực ở đây hay không. – 5gon12eder

+1

Vâng, khấu trừ là vấn đề. Nó là một khoản khấu trừ chính xác, bởi vì nếu không, mọi thứ diễn ra: Bất kỳ chuyên môn nào có thể, hoặc có thể không, có sự chuyển đổi cần thiết. – Deduplicator

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