Select a string template implicitly by passing const char *

Suppose I have my own string class:

class my_string : public std::string { // ... } 

And I want to create a template function that defaults to my_string :

 template <typename TString = my_string> TString do_something(const TString& input) { // ... } 

But when I call it:

 auto result = do_something("abcdef"); 

It calls (of course) do_something<char[7]>() . How to get it to call do_something<my_string> without explicitly specifying the type (i.e. write do_something("abcdef") , not do_something<my_string>("abcdef") )?

+6
source share
3 answers

Define for "construct from string arguments".

 template <typename TString = my_string, typename std::enable_if<std::is_base_of<std::string, TString>::value>::type = nullptr> TString do_something(const TString& input) { // ... } template <typename ...Args, typename std::enable_if<std::is_constructible<my_string, Args....>::value>::type = nullptr> my_string do_something(Args&&... args) { return do_something<my_string>({args}); } 
+3
source

Do you really need a function template? Simple function:

 my_string do_something(my_string const& input) { ... } 

solves your use case. You can pass my_string or a string literal, or even a list bound to init-init, and everything just works.


Since you need a template for other reasons, you can simply provide an overload for const char arrays:

 template <class TString> TString do_something(TString const&) { ... } template <size_t N> my_string do_something(const char (&arr)[N]) { return do_something(my_string{arr, N-1}); } 

Note: There is no reason to provide a default value for the TString template TString . It makes no sense to use this default value.

+1
source

Re

" I want to create a template function that defaults to my_string

 #include <string> template< class Type > struct Explicit_t_ { using T = Type; }; template< class Type > using Explicit_ = typename Explicit_t_<Type>::T; namespace my { struct String: std::string { using std::string::string; }; } // namespace my template< class Some_string > auto do_something( Explicit_<Some_string> const& ) -> Some_string { return "Template func!"; } auto do_something( my::String const& ) -> my::String { return "my::String!"; } #include <iostream> using namespace std; auto main() -> int { cout << do_something( "" ) << endl; // Output "my::String!" cout << do_something<std::string>( "" ) << endl; } 

You can allow the overload for my::String simply forward the function template if you do not want a more specialized or other implementation.

+1
source

All Articles