Suppose I want to create a function that takes both lvalue and rvalue string arguments by refernce, converts them to upper case, and prints them to standard output:
void upper_print(std::string& s);
void upper_print(std::string&& s);
This works fine as follows:
std::string s("Hello world");
upper_print(s);
upper_print(std::string("Hello world"));
upper_print("Hello world"); // converting ctor used
However, to avoid redundancy, I want to use a forwarding reference instead:
template <typename T> upper_print(T&& s);
Unfortunately, then I cannot invoke upper_print
with a string literal argument:
std::string s("Hello world"); // OK
upper_print(s); // OK
upper_print(std::string("Hello world")); // OK
upper_print("Hello world"); // ERROR
I am aware of the possibility to restrict arguments to std::string
objects, e.g., by using std::enable_if
or static_assert
. But it does not help here.
Is there any option to combine the functionality of forwarding references and converting constructor in this sense?
Maybe a solution like this?
template <typename T>
void upper_print_helper(T&& s);
inline void upper_print(std::string&& s) {
upper_print_helper(std::move(s));
}
inline void upper_print(std::string& s) {
upper_print_helper(s);
}