Imagine the following code snippet:
#include <string>
#include <string_view>
template<class T> void foo(std::basic_string_view<T> v) {
// Some work
}
void bar(std::string_view v) {
// Some other work
}
int main() {
std::string x = "abc";
foo<char>(x); // OK
bar(x); // OK
foo(x); // error: std::__cxx11::basic_string<char> is not derived from std::basic_string_view<T>
return 0;
}
Note, that std::basic_string<CharT, Traits, Allocator> has operator std::basic_string_view<CharT, Traits>() const noexcept for consistent template arguments, therefore bar(x) and foo<char>(x) are ok.
In foo, I want to implement a generic algorithm for any character type. However, foo has to be a template function, and T cannot be derived correctly, because implicit type conversions are not respected during template argument type deduction.
The question is the following. Is there any C++ template meta-programming magic to make the last line compiling in a most generic way? I mean that partial solution would be to write a wrapper:
template<class T> void foo(const std::basic_string<T>& v) {
foo(static_cast<std::basic_string_view<T>>(v));
}
but this won't work for other user types convertible to std::basic_string_view<T>.