c++ - std::enable_if_t to separate string from non string function parameters -
i need print kind of string data within double quotation, , others without double quotation.
this functions check if argument string.
template<class t> struct is_str : std::integral_constant<bool, false> {}; template<> struct is_str<char*> : std::integral_constant<bool, true> {}; template<> struct is_str<wchar_t*> : std::integral_constant<bool, true> {}; template<> struct is_str<const char*> : std::integral_constant<bool, true> {}; template<> struct is_str<const wchar_t*> : std::integral_constant<bool, true> {}; template<> struct is_str<std::string> : std::integral_constant<bool, true> {}; template<> struct is_str<const std::string> : std::integral_constant<bool, true> {}; template<> struct is_str<std::wstring> : std::integral_constant<bool, true> {}; template<> struct is_str<const std::wstring> : std::integral_constant<bool, true> {}; and in printer function, use above functions this
template<typename t> std::enable_if_t<is_str<t>::value>, std::ostream&> operator<<(std::ostream& xx, const t& ar) { xx << "\"" << ar << "\""; return xx; } template<typename t> std::enable_if_t<!is_str<t>::value>, std::ostream&> operator<<(std::ostream& xx, const t& ar) { xx << ar; return xx; } it doesn't compile error
unrecognized template declaration/definition
can please tell me how fix or better way handle situation?
graham best right there (bigger, imho) problem.
you're not defining operator<<; you're redefining calling itself.
as far know, it's impossible (you redefine function, compiler doesn't know version call) , when write (inside redefined operator)
xx << "\"" << ar << "\""; which version of operator<<() should used? new redefined (causing loop recursion) or old one?
i think best way exit problem avoid redefine operator<<() , define simple function; example, following print()
template<typename t> std::enable_if_t<is_str<t>::value, std::string> print (t const & ar) { std::ostringstream oss; oss << "\"" << ar << "\""; return oss.str(); } template<typename t> std::enable_if_t<!is_str<t>::value, t const &> print (t const & ar) { return ar; } and use in way
std::cout << print(std::string{"abc"}) << std::endl; // add quotes std::cout << print(1) << std::endl; // no quotes en passant: there couple of classes can useful write more compact code: std::true_type, defined std::integral_constant<bool, true>, , std::false_type, defined std::integral_constant<bool, false>.
so can define is_str follows
template<class t> struct is_str : std::false_type {}; template<> struct is_str<char*> : std::true_type {}; template<> struct is_str<wchar_t*> : std::true_type {}; // ... observe if write
std::cout << print("abc") << std::endl; // add quotes the print() doesn't add quotes.
this because "abc" isn't char const *; it's const char[4].
so, if want add quotes char[n] , wchar_t[n] too, should add following specializations
template<std::size_t n> struct is_str<char[n]> : std::true_type {}; template<std::size_t n> struct is_str<wchar_t[n]> : std::true_type {};
Comments
Post a Comment