I would like to design a template that automatically provides an operator<<(std::ostream&, const T&) for all classes T for which T::print_to(std::ostream&) exists and can be called, so that I can define the printing function as a member function (and, in particular, take advantage of virtual calls).
Through trial and error, I managed to arrive at this:
template<typename T, typename = decltype(std::declval<T>().print_to(std::declval<std::ostream&>()))>
std::ostream &operator<<(std::ostream &s, const T &t) {
t.print_to(s);
return s;
}
It seems to be working, but since I am still new to SFINAE and this kind of tricks, would like to know if there is any pitfall or enhancement that can be made. I put a small test bench at https://ideone.com/uLJxac.
If possible, I would like to have a C++14 solution, because I am working with a C++14 code base. However, if using C++17 allows for a better solution, than I am also interested to that one.
It seems to me that your applying SFINAE correctly in your operator<<(); I don't see pitfalls in your solution.
I propose another version (C++11 compatible, so also C++14) just because require less typewriting
template <typename T>
auto operator<< (std::ostream & s, T const & t)
-> decltype( t.print_to(s), s )
{
t.print_to(s);
return s;
}
Edit:
There is no pitfall with your code, sorry about that. But this answer enables you to write code more like C++20 concept:
template <class T>
auto& operator << (std::ostream &out, const printable_t<T> &t)
{
t.print_to(out);
return out;
}
In fact, I wrote a C++17 concept_check library based on detector and can be used in this way.
For more info on concept support in C++20, have a look at these 2:Constraints and concepts (since c++20) and Constraints and concepts (TS)
Original answer:
std::experiment::is_detector can do the magic for you. Though it is not in standard library, it is not difficult to implement and that link gives the suggested implementation.
Here I will give you how to detect that function along with my implementaion of is_detected_v.
#include <type_traits>
#include <utility>
#include <ostream>
// For support for C++17 is not complete in many compiler, I also define void_t
template <class...> using void_t = void;
namespace impl {
template <class Default, class AlwaysVoid, template <class...> class Op, class ...Args>
struct detector: private std::false_type
{
using std::false_type::value;
using type = Default;
};
template <class Default, template <class...> class Op, class ...Args>
struct detector<Default, void_t<Op<Args...>>, Op, Args...>: private std::true_type
{
using std::true_type::value;
using type = Op<Args...>;
};
} // namespace impl
struct nonsuch {};
#define CONCEPT_T constexpr const static inline bool
template <template<class...> class Op, class ...Args>
CONCEPT_T is_detected_v = impl::detector<nonsuch, void, Op, Args...>::value;
// Detect whether print_to exists.
template <class T>
using print_to_ret_t = decltype( std::declval<T>().print_to( std::declval<std::ostream&>() ) );
template <class T>
CONCEPT_T has_func_print_to_v = is_detected_v<print_to_ret_t, T>;
template <class T, std::enable_if_t< has_func_print_to_v<T> >>
using printable_t = T;
#undef CONCEPT_T
You can try to add C++14 support to this code. It won't be too difficult. The CONCEPT_Tmust be changed to constexpr const static bool to adjust to C++14.
Related
What I am trying to do: define two fmt::formatter templates, one for types that derive from std::exception and one for types that derive from std::array<char, N> so that I can pass these types as parameters to a logging function that uses fmt::format().
Problem: when I define only one of the formatter templates, everything works as expected, but when I define both, I get an error that states that I am redefining a type:
error: redefinition of ‘struct fmt::v7::formatter<T, char, void>’
Code sample:
template<typename T>
concept Exception = std::is_base_of_v<std::exception, T>;
template<std::size_t arrayLen>
template<typename T>
concept CharArray = std::is_base_of_v<std::array<char, arrayLen>, T>;
template <Exception T>
struct fmt::formatter<T> {
constexpr auto parse(format_parse_context& ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const T& ex, FormatContext& ctx) {
return format_to(ctx.out(), "{}", ex.what());
}
};
template <CharArray T>
struct fmt::formatter<T> {
constexpr auto parse(format_parse_context& ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const T& arr, FormatContext& ctx) {
const std::string str{arr.data(), strnlen(arr.data(), arr.size())};
return format_to(ctx.out(), "{}", str);
}
};
Dev environment: g++ 11.1.0, CentOS, fmt from <spdlog/fmt/bundled/format.h>
What I have tried: I tried defining the two concepts Exception and CharArray such that they are mutually exclusive. I have tried using a concept other than CharArray which is not templated on a size argument. I tested that having two void foo(T) functions, one templated on Exception and one on CharArray works as expected.
What I am looking for: At this point, I'm far more interested in an explanation about what I am doing incorrectly than I am in potential work-arounds. I have several work-arounds in mind if it comes to that, but I really want to figure out where my misunderstanding is so I can learn from it.
Thanks in advance for your help and please be kind in your responses.
Solution update: I was defining the CharArray concept incorrectly and it wasn't being caught by GCC. I also needed to move my templates inside the fmt namespace due to a GCC bug.
This:
template<std::size_t arrayLen>
template<typename T>
concept CharArray = std::is_base_of_v<std::array<char, arrayLen>, T>;
is not a valid declaration. I'm surprised the compiler does not flag that as being obviously ill-formed (reported as 102289).
You only get one template head for a concept (the only place you can write multiple such template declarations is when you're defining member function templates of class templates outside of the class body, or other things like that).
The way you can write this concept in C++20 is:
template <std::size_t N>
void f(std::array<char, N> const&);
template <typename T>
concept CharArray = requires (T t) { f(t); }
Basically, if you can call f(t) with a T, then that means that t either is some kind of std::array<char, N> or inherits from one. With additional lambda features in C++20, we can even put that into the concept itself:
template <typename T>
concept CharArray = requires (T t) {
[]<std::size_t N>(std::array<char, N> const&){}(t);
};
The lambda here just exists to do that same "is callable" check that we did with the free function template.
This question already has answers here:
How to detect whether there is a specific member variable in class?
(10 answers)
Closed 2 years ago.
I am going down the route
struct S {
static constexpr int extra=5;
};
struct V {
};
template <typename T>
void f()
{
if (std::is_same_v<decltype(T::extra), int>)
std::cout<< "extra exists" <<std::endl;
}
but calling f<S>() fails as
std::is_same_v<decltype(S::extra), int> == 0
and f<V>() does not compile
If you are stuck in c++17, there is some infrastructure that you can add to make detection like this much easier.
Detection-idiom
The most reusable/consistent way to detect features like this is via the Detection idiom, which leverages SFINAE through std::void_t in a template.
This can be taken verbatim from std::experimental::is_detected's page from cppreference. This effectively offers C++17 the ability to detect features in a way that is similiar to C++20's concepts; and the infrastructure can be reused easily for just about any detection.
The basics of what you would need are:
#include <type_traits>
namespace detail {
template <class Default, class AlwaysVoid,
template<class...> class Op, class... Args>
struct detector {
using value_t = std::false_type;
using type = Default;
};
template <class Default, template<class...> class Op, class... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {
using value_t = std::true_type;
using type = Op<Args...>;
};
} // namespace detail
struct nonesuch{};
template <template<class...> class Op, class... Args>
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
Note: The above infrastructure can be reused for any detection. It is a very useful reusable tool in C++17.
With is_detected, all you need is a detector, which is simply a template alias that evaluates to a decltype expression of something that may, or may not, exist.
So in your case, to conditionally detect the presence of T::extra, you can do this with a simple detector like:
template <typename T>
using detect_extra = decltype(T::extra);
Putting it all together now, you can use this detector to conditionally toggle the branch:
if constexpr (is_detected<detect_extra,T>::value) {
// Only do code if 'T' has 'T::extra' (e.g. 'S')
} else {
// Only do code if 'T' does not have 'T::extra' (e.g. 'V')
}
Live Example
If equivalent conversion to a specific type is important, such as extra needing to be convertible to int, you can also use is_detected_convertible and use the detector to check for if the result can be convertible to the desired type. Using the same cppreference page again, you can define is_detected_convertible as:
template <template<class...> class Op, class... Args>
using detected_t = typename detail::detector<nonesuch, void, Op, Args...>::type;
template <class To, template<class...> class Op, class... Args>
using is_detected_convertible = std::is_convertible<detected_t<Op, Args...>, To>;
Which allows the check to instead be:
if constexpr (is_detected_convertible<int, detect_extra, T>::value) {
// Only do code if 'T' has 'T::extra' convertible to int (e.g. 'S')
} else {
// Only do code if 'T' does not have 'T::extra', or is not int
}
Live Example
Concepts (C++20+ only)
If you have access to c++20 and beyond, concepts make this much simpler -- since you can simply use a concept + requires clause like:
#include <concepts> // std::same_as
template <typename T>
concept HasExtra = requires(T) {
{T::extra} -> std::same_as<int>;
};
if constexpr (HasExtra<T>) {
// Only do code if 'T' has 'T::extra' and is 'int' (e.g. 'S')
} else {
// Only do code if 'T' does not have 'T::extra' (e.g. 'V')
}
Live Example
Observe that decltype(T::extra) (when T is S) is int const (is constexpr so is also const), not int. This explain why f<S>() fails.
To test if a class has a member variable there are many ways, I suppose.
A possible solution is develop something as
void type_extra (...);
template <typename T>
auto type_extra (T t) -> decltype(t.extra);
template <typename T>
using type_extra_t = decltype(type_extra(std::declval<T>()));
Now you can write f() as follows
template <typename T>
void f()
{
if ( not std::is_same_v<type_extra_t<T>, void> )
{
std::cout<< "extra exists" <<std::endl;
if ( std::is_same_v<type_extra_t<T>, int> )
std::cout<< "(and is int)" << std::endl;
}
}
Observe that now the type_extra_t<S> is int, not int const; this way (getting the type from the returned type of a function) loose the constness of the variable.
If you want maintain the constness, you can return a reference from the function (so it return a int const & in the S case)
template <typename T>
auto type_extra (T t) -> decltype(t.extra) &;
and remove the reference from the using (so, in the S case, int const & become int const)
template <typename T>
using type_extra_t
= std::remove_reference_t<decltype(type_extra(std::declval<T>()))>;
I'm trying to learn a bit about templates and metafunctions, namely std::enable_if. I'm making a menu system for our school assignments (extracurricular, mind you), and need a way of getting input from the user. I'd like to define a template class for various types of input - something used along the lines of:
std::string userInput = Input<std::string>("What's your name?").Show();
float userHeight = Input<float>("How tall are you?").Show();
I'd like to (and I'm sure there are reasons not to, but nevertheless) do this generalized sort of conversion using a std::stringstream: get input from user, feed into SS, extract into variable of type T.
It's easy enough to see if the conversion failed during runtime, but I'd like to use std::enable_if to prevent people from using my Input<> class for cases where conversion is impossible, say:
std::vector<Boats> = Input<std::vector<>>("Example").Show();
Obviously a std::stringstream cannot convert a string to a vector, so it will always fail.
My question is this:
Can I format an std::enable_if clause to ONLY allow instantiation of my template class for the types listed above? Alternatively, is there a better way to go about it? Have I got things completely the wrong way around?
What I've done so far
I believe I have found a list of allowed types that std::stringstream can "convert" a string into:
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
I've been using std::enable_if like this up until this point:
template <typename T, typename = typename
std::enable_if<std::is_arithmetic<T>::value, T>::type>
However, now I'd like to extend it to allow not only arithmetic values, but all values supported by the sstream >> operator.
If you prefer to use a SFINAE with a class template parameter, then you want
template <
typename T,
typename = decltype(std::declval<std::istringstream &>() >> std::declval<T &>(), void())
>
class Input /*...*/
I think that you are trying to use std::enable_if for something which doesn't require it. If your template function already relies on operator<< applied on a generic type T, then compilation will fail in any case if the operator is not specialized for that type.
Nothing prevents you from using std::enable_if to solve your specific problem, though that may be not the best way to do it.
If C++20 concepts were already largely adopted I'd say that that would be your way to go.
You could go the way as suggested here on SO and implement a class is_streamable which can check for that like this:
#include <type_traits>
#include <utility>
#include <iostream>
#include <sstream>
template<typename S, typename T>
class is_streamable
{
template<typename SS, typename TT>
static auto test(int)
-> decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
template<typename, typename>
static auto test(...)->std::false_type;
public:
static const bool value = decltype(test<S, T>(0))::value;
};
class C
{
public:
friend std::stringstream& operator<<(std::stringstream &out, const C& c);
};
std::stringstream& operator<<(std::stringstream& out, const C& c)
{
return out;
}
int main() {
std::cout << is_streamable<std::stringstream, C>::value << std::endl;
return 0;
}
This would return one if the operator is implemented and zero if not.
With that you can alter your snippet to
template <typename T, typename = typename
std::enable_if<is_streamable<std::stringstream, C>::value, T>::type>
There are several thing you want:
a trait, is_streamable
a way to forbid class instantiation.
For the traits, you might use std::experimental_is_detected or run your own:
template <typename T>
auto is_streamable_impl(int)
-> decltype (T{},
void(), // Handle evil operator ,
std::declval<std::istringstream &>() >> std::declval<T&>(),
void(), // Handle evil operator ,
std::true_type{});
template <typename T>
std::false_type is_streamable_impl(...); // fallback, ... has less priority than int
template <typename T>
using is_streamable = decltype(is_streamable_impl<T>(0));
Then to forbid intantiation, several choices:
static_assert:
template <typename T>
class Input
{
static_assert(is_streamable<T>::value);
// ...
};
or SFINAE friendly class:
template <typename T, typename = std::enable_if_t<is_streamable<T>>>
class Input
{
// ...
};
so you allow to know if Input<T1> is valid.
Notice that without all that stuff, your program won't compile anyway when instantiating the problematic method (hard error, so no SFINAE friendly).
Being SFINAE friendly is not necessary most of the time.
I'm writing a library for which each value type can be converted to string using a to_string() free function.
I'd like to enable std::ostream& operator<<(std::ostream&, _) for all types T for which to_string(T) is valid. Here is my try:
namespace mylibrary {
// All my types are declared in the `mylibrary` namespace so that ADL is happy.
template <typename T>
inline std::string to_string(const T& value) {
// Return a string for value. Doesn't really matter how.
}
template <typename T>
inline std::ostream& operator<<(std::ostream& os, const T& value) {
return os << to_string(value);
}
}
This actually works... but a bit too well: when resolving os << to_string(value) my templated operator<<() is picked up as candidate even for std::string which sadly makes the call ambiguous an ends up in a compiler error.
I tried using std::enable_if<> to conditionnaly disable my operator<< but sadly I couldn't get something that compiles.
How can I restrict my operator<<() for types for which to_string(T) is a valid expression ?
Alternatively, is there way to restrict my operator<<() for types which are defined in my namespace ?
You can use expression-SFINAE to restrict the template overload set. For example like this:
#include <string>
#include <type_traits>
template <typename> using void_t = void;
template <typename T, typename = void_t<decltype(to_string(std::declval<T>()))>>
std::ostream& operator<<(std::ostream& os, const T& value) {
return os << to_string(value);
}
(You should probably wrap this up somehow so as not to have a visible second template parameter in your public template; users will discover and abuse it.)
namespace details{
template<template<class...>class,class,class...>
struct can_apply:std::false_type{};
template<template<class...>class Z,class...Ts>
struct can_apply<Z,std::void_t<Z<Ts...>>,Ts...>:
std::true_type
{};
}
template<template<class...>class Z,class...Ts>
using can_apply=details::can_apply<Z,void,Ts...>;
is a small metaprogramming library that gives you the can_apply<template, types...> trait. It uses C++1z std::void_t which is easy to write if your compiler lacks it.
template<class X>
using to_string_t=decltype(to_string(std::declval<X>()));
is a SFINAE enabled "type of calling to_string" (either string or error, we hope). We stitch together:
template<class X>
using can_to_string=can_apply<to_string_t,X>;
and we have a trait can_to_string which is true iff you can to_string. Both of the above two using templates shoud be in the same namespace as your to_string for built-in types for adl reasons.
Now we can write our <<:
template <class T,class=std::enable_if_t<can_to_string<const T&>{}>>
inline std::ostream& operator<<(std::ostream& os, const T& value) {
return os << to_string(value);
}
The modest metaprogramming library overhead makes the final code much cleaner than alternatives.
enable_if_t is C++14 but also easy to write in C++11. You may have to replace {} with ::value in C++11 within the enable_if as well.
The result_t using alias is one line, the can_ alias is another, and then we have a friendly can_ alias for almost any bit of C++ code, which allows for clean enable_if SFINAE.
All of this can be done on one line, but I find the resulting << interface to be less than clear in what the requirements are.
I would like to make a type trait for checking if a particular type is hashable using the default instantiations of the standard library's unordered containers, thus if it has a valid specialization for std::hash. I think this would be a very useful feature (e.g. for using std::set as failsafe for std::unordered_set in generic code). So I, thinking std::hash is not defined for each type, started making the following SFINAE solution:
template<typename T> std::true_type hashable_helper(
const T&, const typename std::hash<T>::argument_type* = nullptr);
template<typename T> std::false_type hashable_helper(...);
//It won't let me derive from decltype directly, why?
template<typename T> struct is_hashable
: std::is_same<decltype(hashable_helper<T>(std::declval<T>())),
std::true_type> {};
(Forgive my modest SFINAE-abilities if this is not the best solution or even wrong.)
But then I learned, that both gcc 4.7 and VC++ 2012 define std::hash for any type T, just static_asserting in the non-specialized version. But instead of compiling conditionally they (and also clang 3.1 using gcc 4.7's libstdc++) fail the assertion resulting in a compile error. This seems reasonable since I think static_asserts are not handled by SFINAE (right?), so an SFINAE solution seems not possibly at all. It's even worse for gcc 4.6 which doesn't even have a static_assert in the general std::hash template but just doesn't define its () operator, resulting in a linker error when trying to use it (which is always worse than a compile error and I cannot imagine any way to transform a linker error into a compiler error).
So is there any standard-conformant and portable way to define such a type trait returning if a type has a valid std::hash specialization, or maybe at least for the libraries static_asserting in the general template (somehow transforming the static_assert error into a SFINAE non-error)?
Since C++17 it is now possible to do this in a more elegant way.
From cppreference about std::hash:
Each specialization of this template is either enabled ("untainted") or disabled ("poisoned"). For every type Key for which neither the library nor the user provides an enabled specialization std::hash, that specialization exists and is disabled. Disabled specializations do not satisfy Hash, do not satisfy FunctionObject, and std::is_default_constructible_v, std::is_copy_constructible_v, std::is_move_constructible_v, std::is_copy_assignable_v, std::is_move_assignable_v are all false. In other words, they exist, but cannot be used.
This meant that the STL had to remove the static_assert in C++17. Here is a working solution with 'Clang-6.0.0 -std=c++17':
#include <functional>
#include <ios>
#include <iostream>
#include <type_traits>
template <typename T, typename = std::void_t<>>
struct is_std_hashable : std::false_type { };
template <typename T>
struct is_std_hashable<T, std::void_t<decltype(std::declval<std::hash<T>>()(std::declval<T>()))>> : std::true_type { };
template <typename T>
constexpr bool is_std_hashable_v = is_std_hashable<T>::value;
struct NotHashable {};
int main()
{
std::cout << std::boolalpha;
std::cout << is_std_hashable_v<int> << std::endl;
std::cout << is_std_hashable_v<NotHashable> << std::endl;
return 0;
}
This might for example come in handy when you use boost::hash_combine or boost::hash_range. If you include a header containing the following code sample you do not need to define boost hashes for specific types anymore.
#include <boost/functional/hash_fwd.hpp>
template <typename T, typename = std::void_t<>>
struct is_boost_hashable : std::false_type { };
template <typename T>
struct is_boost_hashable<T, std::void_t<decltype(boost::hash_value(std::declval<T>()))>> : std::true_type { };
template <typename T>
constexpr bool is_boost_hashable_v = is_boost_hashable<T>::value;
namespace boost
{
template <typename T>
auto hash_value(const T &arg) -> std::enable_if_t<is_std_hashable_v<T> &&
!is_boost_hashable_v<T>, std::size_t>
{
return std::hash<T>{}(arg);
}
}
Notice the is_boost_hashable_v, this is necessary to avoid ambiguity as boost already provides hashes for a lot of hashes.
It seems we have two conflicting requirements:
SFINAE is meant to avoid any instantiation of a template if the instantiation might fail and remove the corresponding function from the overload set.
static_assert() is meant to create an error, e.g., during instantiation of a template.
To my mind, 1. clearly trumps 2., i.e., your SFINAE should work. From the looks of two separate compiler vendors disagree, unfortunately not between themselves but with me. The standard doesn't seem to specify how the default definition of std::hash<T> looks like and seems to impose constraints only for the cases where std::hash<T> is specialized for a type T.
I think your proposed type traits is a reasonable idea and it should be supported. However, it seems the standard doesn't guarantee that it can be implemented. It may be worth bringing this up with the compiler vendors and/or filing a defect report for the standard: The current specification doesn't give clear guidance what should happen, as far as I can tell. ... and if the specification currently mandates that a type traits as above fails it may be a design error which needs to be corrected.
Here is a VERY dirty solution to your problem: It works for GCC 4.7 (and not 4.6, due to missing C++11 feature: mangling overload)
// is_hashable.h
namespace std {
template <class T>
struct hash {
typedef int not_hashable;
};
}
#define hash hash_
#define _Hash_impl _Hash_impl_
#include<functional>
#undef hash
#undef _Hash_impl
namespace std {
struct _Hash_impl: public std::_Hash_impl_{
template <typename... Args>
static auto hash(Args&&... args)
-> decltype(hash_(std::forward<Args>(args)...)) {
return hash_(std::forward<Args>(args)...);
}
};
template<> struct hash<bool>: public hash_<bool> {};
// do this exhaustively for all the hashed standard types listed in:
// http://en.cppreference.com/w/cpp/utility/hash
}
template <typename T>
class is_hashable
{
typedef char one;
typedef long two;
template <typename C> static one test( typename std::hash<C>::not_hashable ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(long) };
};
// main.cpp
// #include "is_hashable.h"
#include<iostream>
#include<unordered_set>
class C {};
class D {
public:
bool operator== (const D & other) const {return true;}
};
namespace std {
template <> struct hash<D> {
size_t operator()(const D & d) const { return 0;}
};
}
int main() {
std::unordered_set<bool> boolset;
boolset.insert(true);
std::unordered_set<D> dset;
dset.insert(D());// so the hash table functions
std::cout<<is_hashable<bool>::value<<", ";
std::cout<<is_hashable<C>::value << ", ";
std::cout<<is_hashable<D>::value << "\n";
}
And the output is:
1, 0, 1
We basically "hijack" the hash symbol and inject some helper typedef in it. You'll need to modify it for VC++, in particular, the fix for _Hash_impl::hash() since it's an implementation detail.
If you make sure that the section labelled as is_hashable.h is included as the first include this dirty trick should work...
I hit this too. I tried a few workarounds and went with a whitelist filter for std::hash<>. the whitelist is not pleasant to maintain, but it is safe and it works.
I tried this on VS 2013, 2015, clang and gcc.
#include <iostream>
#include <type_traits>
// based on Walter Brown's void_t proposal
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3911.pdf
namespace detail {
template<class... TN> struct void_t {typedef void type;};
}
template<class... TN>
struct void_t {typedef typename detail::void_t<TN...>::type type;};
// extensible whitelist for std::hash<>
template <class T, typename = void>
struct filtered_hash;
template <class T>
struct filtered_hash<T,
typename std::enable_if<std::is_enum<T>::value>::type>
: std::hash<T> {
};
template <class T>
struct filtered_hash<T,
typename std::enable_if<std::is_integral<T>::value>::type>
: std::hash<T> {
};
template <class T>
struct filtered_hash<T,
typename std::enable_if<std::is_pointer<T>::value>::type>
: std::hash<T> {
};
template<typename, typename = void>
struct is_hashable
: std::false_type {};
template<typename T>
struct is_hashable<T,
typename void_t<
typename filtered_hash<T>::result_type,
typename filtered_hash<T>::argument_type,
typename std::result_of<filtered_hash<T>(T)>::type>::type>
: std::true_type {};
// try it out..
struct NotHashable {};
static_assert(is_hashable<int>::value, "int not hashable?!");
static_assert(!is_hashable<NotHashable>::value, "NotHashable hashable?!");
int main()
{
std::cout << "Hello, world!\n";
}