Я играл с «перегрузкой» лямбда, как представлено here, и быстро дошел до того места, где мне было бы удобно создавать специализированные закрылки лямбда. Так что я был первым методом проб и error'ing немного, с моим самым многообещающим испытание бытьC++ специализируется на лямбда для определенного типа
auto call_for_vector = [] template<typename T> (std::vector<T>) {};
Однако позже взгляд на cppreference показал, что ни это, ни подобные конструкции, как представляется, допускается стандартом.
В чем причина такой специализации не поддерживается?
Я знаю, что это можно получить с помощью SFINAE, но тогда оно менее читаемо, труднее писать и подвержено большей подверженности ошибкам. Конечно, можно также Simpy написать класс с соответствующим operator()
, но это Су C++ 03 :-)
Какая польза была бы для такого синтаксиса ?:
Одним из примеров, это позволило бы легко лямбда «перегрузки», как показано в следующем коде
template <class F1, class F2>
struct overload_set : F1, F2
{
overload_set(F1 x1, F2 x2) : F1(x1), F2(x2) {}
using F1::operator();
using F2::operator();
};
template <class F1, class F2>
overload_set<F1,F2> overload(F1 x1, F2 x2)
{
return overload_set<F1,F2>(x1,x2);
}
auto f = overload(
[](auto&& x){ std::cout<<"call by default"<<std::endl;},
[] template<typename T>(std::vector<T>){std::cout<<"call for vector"<<std::endl;}
);
можно получить такое поведение, например, используя базу SFINAE по технике в this answer, но опять же ... это отстой.
Есть ли у SFINAE легкое обходное решение для получения конкретных перегрузок?
ну, я думаю, вы являетесь familliar с std :: function, что является способом работы с прочными функциями. Я думаю, что лямбды неустойчивы в том смысле, что стандарт не хотел бы, чтобы вы их хранили, равно –
@David Haim: вышеупомянутое не работает с 'std :: function', так как ему нужна определенная подпись. – davidhigh
вы можете templatetize std :: function, 'template std :: function ' вы не можете сделать это с помощью lambda –