有没有办法让这段代码编译?我希望将我的比较函数作为lambda模板参数。
#include <iostream>
#include <set>
int main()
{
std::set<int*, [](int *a, int *b){return *a<*b;}> S;
return 0;
}
我收到以下错误:
prog.cpp: In function ‘int main()’:
prog.cpp:6:17: error: lambda-expression in template-argument
std::set<int*, [](int *a, int *b){return *a<*b;}> S;
^
prog.cpp:6:51: error: template argument 2 is invalid
std::set<int*, [](int *a, int *b){return *a<*b;}> S;
任何人都可以帮我修改代码,或解释为什么不可能吗?
答案 0 :(得分:10)
您的代码无效,因为:
[](int *a, int *b){return *a<*b;}
...不是类型,它是(实现定义类型的)对象,因此您不能将其用作模板参数。
您可以先创建对象,然后使用decltype
找到其类型:
auto comp = [](int *a, int *b){ return *a<*b; };
std::set<int*, decltype(comp)> S{comp};
或者在C ++ 20中,您可以直接应用decltype
:
std::set<int*, decltype([](int *a, int *b){return *a<*b;})> S;
由于lambda是无捕获的,另一种方法是使用比较器类型的函数指针类型,让编译器将无捕获的lambda转换为函数指针:
std::set<int*, bool (*)(int*, int*)> S([](int *a, int *b){ return *a<*b; });
答案 1 :(得分:1)
现在回答,但如果您想要写,这是另一种选择 您的比较器内联而不指定类型..
#include <iostream>
#include <set>
template <typename ,typename>
struct swap_set_comparator{};
template <typename new_comp,typename set_type,typename comp,typename alloc>
struct swap_set_comparator<new_comp,std::set<set_type,comp,alloc> >
{
using type = std::set<set_type,new_comp,alloc>;
};
template <typename container, typename... Args,typename Func>
auto make_set(Args&&... args,Func&& f)
{
return typename swap_set_comparator<Func,container>::type(std::forward<Args>(args)...,std::forward<Func>(f));
}
int main()
{
// as already answered..
auto comparator = [](int *a, int *b){return *a<*b;};
std::set<int*,decltype(comparator)> S(comparator);
// or
auto S2 = make_set<std::set<int*>>([](int *a, int *b){return *a<*b;});
return 0;
}