A response from Oktalist explains why the trait of your type does not compile. In addition, you should not use __and_ and __not_ . They are reserved and can easily be changed in the next version of the compiler. It is enough to simply implement your own version of these signs (for example, see a possible implementation of conjunction ).
I would suggest a completely different approach. We can use choice<> to make overloading these cases much easier:
template <int I> struct choice : choice<I+1> { }; template <> struct choice<10> { };
Via:
// arithmetic version template <class T> auto convertToStringHelper(T const& t, choice<0> ) -> decltype(std::to_string(t)) { return std::to_string(t); } // non-arithmetic version template <class T> auto convertToStringHelper(T const& t, choice<1> ) -> decltype(std::string(t)) { return std::string(t); } // vector version template <class T, class A> std::string convertToStringHelper(std::vector<T,A> const& v, choice<2> ) { // implementation here } template <class T> std::string convertToString(T const& t) { return convertToStringHelper(t, choice<0>{}); }
This is nice because you get all SFINAE without the enable_if slope.
Barry source share