The following does not compile:
#include <iostream>
#include <type_traits>
template <class F, class G>
auto static_if (std::true_type, F && f, G && g) {
return std::forward<F> (f) (0);
}
template <class F, class G>
auto static_if (std::false_type, F && f, G && g) {
return std::forward<G> (g) (0);
}
template <class T> std::true_type constexpr is_pointer (T *) { return {}; }
template <class T> std::false_type constexpr is_pointer (T) { return {}; }
int main() {
int x = 5;
static_if (
is_pointer (x),
[&] (auto) { std::cout << *x << std::endl; },
[&] (auto) { std::cout << "no pointer" << std::endl; }
);
return 0;
}
Compilation fails with the error message:
prog.cpp: In lambda function:
prog.cpp:23:33: error: invalid type argument of unary '*' (have 'int')
[&] (auto) { std::cout << *x << std::endl; },
See here: http://ideone.com/frl8rn
Now the question is: Why?
It is clear that compilation should fail if the lambdas were not generic (no auto
parameter).
Yet we have two generic lambdas here. Each of them should only be instantiated when it is used (which means: called, or, at least, when its operator ()
is somehow referenced).
The generic lambda generating the error message should therefore not be instantiated, since the second overload of static_if
is used, in the definition of which the parameter f
is not called. Since the generic lambda's operator ()
is not used, the compiler should simply ignore it.
Where is my reasoning wrong?