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

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -