I'm learning about function template specialization in C and am tasked with writing a template function called plus
that returns the sum of it's two arguments which maybe of different types. One version that accepts by value and another by pointer. As an added challenge, I'm asked to overload this function so that it concatenates two strings.
template <typename T1, typename T2> decltype(auto) plus(const T1& a, const T2& b) {
return a b;
}
template <typename T1, typename T2> decltype(auto) plus(const T1* a, const T2* b) {
return *a *b;
}
// concatenate two strings
template <>
std::string_view plus<std::string_view, std::string_view> (std::string_view a, std::string_view b) {
return std::string { a } std::string{ b };
}
The problem is that I'm getting an error on the specialization overload of the function to concatenate two strings. The reason I decided to choose std::string_view
over std::string
is so that when calling the function with string literals (const char*
) it wouldn't resolve to the second definition that accepts a const *
which I'm guessing would be resolved over std::string
.
So I can't really figure out what's going on. Just a wild guess but maybe this has something to do with me having two different template functions called plus
and it can't figure out which one I'm trying to specialize / overload?
UPDATE:
The issue seems to be with template resolution. The definition that accepts const T*
is always preferred for any string literals. Just trying to find a fix.
CodePudding user response:
This would be my suggestion:
template <typename T1, typename T2, typename T3> T3 plus(const T1& a, const T2& b) {
return a b;
}
template <typename T1, typename T2, typename T3> T3 plus(const T1* a, const T2* b) {
return *a *b;
}
template <typename T1, typename T2, typename T3> T3 plus(T1 a, T2 b) {
return a b;
}
// concatenate two strings
template <>
std::string plus<std::string_view, std::string_view> (std::string_view a, std::string_view b) {
return std::string(a).append(b);
}
Since string views needs to refer to the content of another string you need to return a string since the newly created string_view would point to a temporary object.
Also there is no way to concatenate 2 string_view's together since concatenating two strings together would require that string_view's are able to hold references to other string views (since they don't hold string content themselves).
Furthermore, a third typename is required since this implementation would return another type (std::string) since you don't want to return a string_view of a temporary