Until this feature becomes available, I take advantage of such a trick:
#include <type_traits>
#include <iostream>
using namespace std;
template <bool>
struct constexpr_if;
template <>
struct constexpr_if<true> {
struct elser {
template <
class F,
class... Args
>
void _else(F&&, Args&&...) {
}
template <
bool C,
class F,
class... Args
>
auto _else_if(F&&, Args&&...) {
return elser();
}
};
template <
class F,
class... Args
>
auto operator()(F&& callback, Args&&... args) {
callback(std::forward<Args>(args)...);
return elser();
}
};
template <>
struct constexpr_if<false> {
struct elser {
template <
bool C,
class F,
class... Args
>
auto _else_if(F&& callback, Args&&... args) {
return constexpr_if<C>()(std::forward<F>(callback), std::forward<Args>(args)...);
}
template <
class F,
class... Args
>
void _else(F&& callback, Args&&... args) {
callback(std::forward<Args>(args)...);
}
};
template <
class F,
class... Args
>
auto operator()(F&& callback, Args&&... args) {
return elser();
}
};
int main() {
constexpr_if<true>()(
[](auto...){
cout << "1 ";
}
)._else_if<true>(
[](auto...){
static_assert(false, "Error");
}
)._else(
[](auto...){
static_assert(false, "Error");
}
);
constexpr_if<false>()(
[](auto...){
static_assert(false, "Error");
}
)._else_if<true>(
[](auto...){
cout << "2 ";
}
)._else(
[](auto...){
static_assert(false, "Error");
}
);
constexpr_if<false>()(
[](auto...){
static_assert(false, "Error");
}
)._else_if<false>(
[](auto...){
static_assert(false, "Error");
}
)._else_if<true>(
[](auto...){
cout << "3 ";
}
)._else(
[](auto...){
static_assert(false, "Error");
}
);
constexpr_if<false>()(
[](auto...){
static_assert(false, "Error");
}
)._else(
[](auto...){
cout << "4" << endl;
}
);
int c;
cin >> c;
}
int main() has several tests for this template hack. It successfully outputs "1 2 3 4 " to the standard output, without hitting the static_asserts, thus completely omitting compilation for lambdas for whom the conditions do not hold.
Note that the lambda must necessarily be generic for its body compilation to be omitted when the specialization yields an empty operator().