1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include <iostream>
#include <type_traits>
template <typename T, typename K> struct Nothing;
template <typename T, typename K>
std::ostream& operator<< (std::ostream&, const Nothing<T, K>&);
template <typename T, typename K> struct Nothing {
K something() const;
K operator()(const K&) const;
friend std::ostream& operator<< <>(std::ostream&, const Nothing<T, K>&);
};
template <typename T, typename K> K Nothing<T, K>::something() const
{
return T()();
}
template <typename T, typename K> K Nothing<T, K>::operator()(const K& val) const
{
return T()(val);
}
template <typename T, typename K>
std::ostream& operator<< (std::ostream& os, const Nothing<T, K>& rhs)
{
os << rhs.something();
return os;
}
template <typename T> struct Something {
template <typename K = T>
std::enable_if_t <std::is_integral_v<K>, K> operator() () const;
template <typename K = T>
std::enable_if_t <std::is_floating_point_v<K>, K> operator() () const;
};
template <typename T>
template <typename K>
std::enable_if_t <std::is_integral_v<K>, K> Something<T>::operator()() const
{
return 299792458;
}
template <typename T>
template <typename K>
std::enable_if_t <std::is_floating_point_v<K>, K> Something<T>::operator()() const
{
return 3.141592653589793238462643383279502884197169399375105820974944;
}
auto anything { [](const auto& val) -> bool { return val % 2; } };
int main()
{
std::cout << "The speed of light in vacuum is "
<< Nothing<Something<int>, int>()
<< " m/s,\nthe greek PI is approximately "
<< Nothing<Something<double>, double>()
<< ",\nand 13 is "
<< ( Nothing<decltype(anything), bool>()(13) ? "odd" : "even" )
<< '\n';
}
| |