Let's take a simple SFINAE templating example
#include <iostream>
template <typename T>
struct has_typedef_foobar {
// Types "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test(typename C::foobar*);
template <typename>
static no& test(...);
// If the "sizeof" of the result of calling test<T>(0) would be equal to sizeof(yes),
// the first overload worked and T has a nested type named foobar.
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
struct foo {
typedef float foobar;
};
int main() {
std::cout << std::boolalpha;
std::cout << has_typedef_foobar<int>::value << std::endl;
std::cout << has_typedef_foobar<foo>::value << std::endl;
}
The bool
value has not been declared constexpr
but it still gets its value on compile time. What then is the use of constexpr
and why do simple static variables get their values at compile time? How can I tell which static variables get their value at compile time?
Also how can I tell which values will get evaluated at compile time and which will not? Will using constexpr
guarantee compile time evaluation? If not how can I know which will happen (compile time or run time)?