How to properly implement a function with variadic number of std::string_view arguments?

  • A+
Category:Languages

Desired behavior

What I basically want is to create a function like this:

void func(std::string_view... args) {     (std::cout << ... << args); } 

It should be able to work only with classes that are convertible to std::string_view.

Example:

int main() {     const char* tmp1 = "Hello ";     const std::string tmp2 = "World";     const std::string_view tmp3 = "!";      func(tmp1, tmp2, tmp3, "/n");      return 0; } 

should print: Hello World!


Accomplished behavior

So far, I got here:

template<typename... types> using are_strings = std::conjunction<std::is_convertible<types, std::string_view>...>;  template<typename... strings, class = std::enable_if_t<are_strings<strings...>::value, void>> void func(strings... args) {     (std::cout << ... << args); }  int main() {     const char* tmp1 = "Hello ";     const std::string tmp2 = "World";     const std::string_view tmp3 = "!";      func(tmp1, tmp2, tmp3, "/n");      return 0; } 

This actually works as expected, but there is still one big problem.


Problem

Only classes that are convertible to std::string_view can be used in this function and that's great.
However, even though classes are convertible, they are not converted to std::string_view!

This leads to needless copying of data(for example when std::string is passed as argument).


Question

Is there a way to force implicit conversion of variadic arguments to std::string_view?


Note

I know about std::initializer_list, but I would like to keep function call simple, without {}.

 


namespace impl{   template<class...SVs>   void func(SVs... svs){     static_assert( (std::is_same< SVs, std::string_view >{} && ...) );     // your code here   } } template<class...Ts,   std::enable_if_t< (std::is_convertible<Ts, std::string_view >{}&&...), bool > =true > void func( Ts&&...ts ){   return impl::func( std::string_view{std::forward<Ts>(ts)}... ); } 

or somesuch.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: