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