Haggai Magen
Haggai Magen

Reputation: 103

C++ Templates Specialization Ponderings

I ran into a strange situation that should be solved with templates, but for some reason I fail to find the right way to do it.

for most basic types (int, bool, char, double, long...) I use this function:

template <typename T>
T foo(T val);

The special case is with strings, since sending an argument to the function in all cases is by sending a quoted text (like "blah") which is deduced to a const char*, and the return value must be std::string like this:

template ?
std::string foo(const char* val);

The code for all the basic types is the same, but the string case is special since the argument and the return value types are not the same, and the string case requires different code than the basic case.

I've tried all kinds of strange combinations to achieve a code that compiles and works but I failed. I need a solution that is more elegant than writing the same code over and over again.

Thanks!

Upvotes: 1

Views: 61

Answers (2)

bolov
bolov

Reputation: 75688

Just add a non-templated overload:

std::string foo(const char* str)
{
      return foo(std::string{str});
      //or
      // return foo<std::string>(str);
}
std::string foo(char* str); // might need this too

Depending on your case, you could consider this fist (or instead):

template <std::size_t N>
std::string foo(const char(&str)[N])
{
    return foo(std::string{str});
    //or
    // return foo<std::string>(str);
}

String literals are of type array, but they decay to pointers. E.g. "asd" is of type const char[4]. So this is a better fit for string literals.

Upvotes: 7

Jarod42
Jarod42

Reputation: 217085

Whereas the simple overload may be preferred (std::string foo(const char* val);), you may use a sort of traits for return type:

template <typename T>
struct fooRet
{
    using type = T;
};

template <>
struct fooRet<const char*>
{
    using type = std::string;
};

And then

template <typename T>
typename fooRet<T>::type foo(T val);

can be specialized (if still needed) for const char*

Upvotes: 3

Related Questions