c++ - C++11 does not deduce type when std::function or lambda functions are involved -


when define function,

template<class a> set<a> test(const set<a>& input) {     return input; } 

i can call using test(myset) elsewhere in code without having explicitly define template type. however, when use following function:

template<class a> set<a> filter(const set<a>& input,function<bool(a)> compare) {     set<a> ret;     for(auto = input.begin(); != input.end(); it++) {         if(compare(*it)) {             ret.insert(*it);         }     }     return ret; } 

when call function using filter(myset,[](int i) { return i%2==0; }); following error:

error: no matching function call ‘filter(std::set<int>&, main()::<lambda(int)>)’ 

however, of these versions do work:

std::function<bool(int)> func = [](int i) { return i%2 ==0; }; set<int> mynewset = filter(myset,func);  set<int> mynewset = filter<int>(myset,[](int i) { return i%2==0; });  set<int> mynewset = filter(myset,function<bool(int)>([](int i){return i%2==0;})); 

why c++11 unable guess template type when put lambda function directly inside expression without directly creating std::function?

edit:

per advice of luc danton in comments, here alternative function had earlier not need templates passed explicitly.

template<class a,class comparefunction> set<a> filter(const set<a>& input,comparefunction compare) {     set<a> ret;     for(auto = input.begin(); != input.end(); it++) {         if(compare(*it)) {             ret.insert(*it);         }     }     return ret; } 

this can called set<int> result = filter(myintset,[](int i) { % 2 == 0; }); without needing template.

the compiler can guess return types extent, using new decltype keyword , using new function return type syntax. here example converts set map, using 1 filtering function , 1 function generates keys based on values:

template<class value,class comparetype,class indextype> auto filter(const set<value>& input,comparetype compare,indextype index) -> map<decltype(index(*(input.begin()))),value> {     map<decltype(index(*(input.begin()))),value> ret;     for(auto = input.begin(); != input.end(); it++) {         if(compare(*it)) {             ret[index(*it)] = *it;         }     }     return ret; } 

it can called without using template directly, as

map<string,int> s = filter(myintset,[](int i) { return i%2==0; },[](int i) { return tostring(i); }); 

the issue on nature of lambdas. function objects fixed set of properties according standard, not function. standard determines lambdas can converted std::function<> exact types of arguments and, if have no state, function pointers.

but not mean lambda std::function nor function pointer. unique types implementing operator().

type deduction, on other hand, deduce exact types, no conversions (other const/volatile qualifications). because lambda not std::function compiler cannot deduce type in call: filter(myset,[](int i) { return i%2==0; }); std::function<> instantiation.

as of other examples, in first 1 convert lambda function type, , pass that. compiler can deduce type there, in third example std::function rvalue (temporary) of same type.

if provide instantiating type int template, second working example, deduction not come play compiler use type , convert lambda appropriate type.


Comments

Popular posts from this blog

android - Gradle sync Error:Configuration with name 'default' not found -

java - Andrioid studio start fail: Fatal error initializing 'null' -

html - jQuery UI Sortable - Remove placeholder after item is dropped -