Can I limit the overall lambda with some make_if tricks?
If all you want is to limit the parameter types of your common lambda, you can do this with a few function declarations (without a definition) and static_assert (so you get a static_assert message error at compile time in case of failure). No macros at all (they are such C-ish).
This follows a minimal working example:
#include<vector> #include<type_traits> #include<utility> #include<list> template<template<typename...> class C, typename... A> constexpr std::true_type spec(int, C<A...>); template<template<typename...> class C, template<typename...> class T, typename... A> constexpr std::false_type spec(char, T<A...>); int main() { auto fn = [](auto&& v) { static_assert(decltype(spec<std::vector>(0, std::declval<std::decay_t<decltype(v)>>()))::value, "!"); // ... }; fn(std::vector<int>{}); // fn(std::list<int>{}); //fn(int{}); }
If you switch the comments to the last lines, static_assert will static_assert error and the compilation will fail. Look at it and launch wandbox .
Side note.
Of course, you can reduce the template here:
static_assert(decltype(spec<std::vector>(0, std::declval<std::decay_t<decltype(v)>>()))::value, "!");
Add a variable template, for example the following:
template<template<typename...> class C, typename T> constexpr bool match = decltype(spec<C>(0, std::declval<std::decay_t<T>>()))::value;
Then use it in static_assert s:
static_assert(match<std::vector, decltype(v)>, "!");
Pretty clear, right?
Note.
In C ++ 17, you can further reduce the code needed to do this by defining your lambda as:
auto fn = [](auto&& v) { if constexpr(match<std::vector, decltype(v)>) { print(v); } };
See sample code running on wandbox .