#include <iostream>
#include <type_traits>
template <int N>
struct Fibonacci {
static constexpr int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;
};
template <>
struct Fibonacci<0> {
static constexpr int value = 0;
};
template <>
struct Fibonacci<1> {
static constexpr int value = 1;
};
template <typename T>
struct IsPointer : std::false_type {};
template <typename T>
struct IsPointer<T*> : std::true_type {};
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
getValue(T t) {
return t;
}
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, T>::type
getValue(T t) {
return T();
}
int main() {
constexpr int fib5 = Fibonacci<5>::value;
std::cout<<"fib5="<<fib5<<std::endl;
constexpr int fib6 = Fibonacci<6>::value;
std::cout<<"fib6="<<fib6<<std::endl;
constexpr int fib7 = Fibonacci<7>::value;
std::cout<<"fib7="<<fib7<<std::endl;
constexpr bool intIsPointer = IsPointer<int>::value;
constexpr bool intPtrIsPointer = IsPointer<int*>::value;
std::cout<<"intIsPointer="<<intIsPointer<<std::endl;
std::cout<<"intPtrIsPointer="<<intPtrIsPointer<<std::endl;
std::cout << getValue(10) << std::endl;
std::cout << getValue(3.14) << std::endl;
return 0;
}