我想在 std::map 构造的时候直接使用 Lambda 表达式指定排序方式, 但是编译器报错了
class Person {
public:
std::string name;
int age;
Person(const std::string & n , int a) {
name = n;
age = a;
}
class Compare {
public:
bool operator()(const Person & lhs, const Person & rhs) {
return lhs.age < rhs.age;
}
};
};
auto lambda = [](const Person & lhs, const Person & rhs){
return lhs.age < rhs.age;
};
auto wapper = [lambda]() {
return lambda;
};
bool a = Person::Compare()(Person("p1", 1), Person("p2", 2));
bool b = wapper()(Person("p1", 1), Person("p2", 2));
// Success
std::set<Person, Person::Compare> sp;
// E: Template argument for template type parameter must be a type
std::set<Person, wapper> sp;
1
noli 2019-08-21 22:37:00 +08:00 1
std::bind
|
3
ysc3839 2019-08-21 22:57:31 +08:00 via Android 1
std::set<Person, decltype(lambda)> sp(lambda);
|
4
noli 2019-08-21 23:03:45 +08:00
|
5
wisan 2019-08-21 23:05:09 +08:00 via Android 1
lambda 要用 std::move,不然不能拷贝。。更别说当参数了。。
|
8
geelaw 2019-08-21 23:11:27 +08:00 via iPhone 1
说得够明白了:代替 Person::Compare 的必须是一个类型,你的 wapper 不是一个类型,而是一个对象。
你可以这样 template <typename TElement, typename TCompare> std::set<TElement, TCompare> make_set(TCompare &&cmp) { return {}; } auto my_set = make_set<Person>([](Person const &a, Person const &b) { return a.age < b.age; }); |
9
blinue 2019-08-21 23:25:18 +08:00 1
Compare 在 set 里被默认构造用于比较,lambda 对象的默认构造函数被删除,decltype(lambda)在 C++20 前行不通,只能定义新的类。在 C++20 里,不捕获的 lamda 对象的类型具有默认构造函数,就可以这样了:set<Person, decltype(lambda)>。
|
10
sl0000 OP @geelaw 这个编译不能通过呀, 提示
```` In file included from ~/Desktop/learnC++/LearnC++/main.cpp:11: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/set:458:19: error: no matching constructor for initialization of 'std::__1::set<Person, (lambda at ~/Desktop/learnC++/LearnC++/main.cpp:36:32), std::__1::allocator<Person> >::value_compare' (aka '(lambda at /Users/cosmojulis/Desktop/learnC++/LearnC++/main.cpp:36:32)') : __tree_(value_compare()) {} ^ ~/Desktop/learnC++/LearnC++/main.cpp:34:12: note: in instantiation of member function 'std::__1::set<Person, (lambda at ~/Desktop/learnC++/LearnC++/main.cpp:36:32), std::__1::allocator<Person> >::set' requested here return {}; ^ ~/Desktop/learnC++/LearnC++/main.cpp:36:15: note: in instantiation of function template specialization 'make_set<Person, (lambda at ~/Desktop/learnC++/LearnC++/main.cpp:36:32)>' requested here auto my_set = make_set<Person>([](const Person & a, const Person & b) ^ ~/Desktop/learnC++/LearnC++/main.cpp:36:32: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided auto my_set = make_set<Person>([](const Person & a, const Person & b) ^ ~/Desktop/learnC++/LearnC++/main.cpp:36:32: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided ```` |
11
sl0000 OP 感谢各位大佬, 今天学到特别多, 我睡了
|