Пересылка ссылок и преобразование конструкторов в C++

Предположим, я хочу создать функцию, которая принимает строковые аргументы lvalue и rvalue по ссылке, преобразует их в верхний регистр и печатает их в стандартный вывод:

void upper_print(std::string& s);
void upper_print(std::string&& s);

Это прекрасно работает следующим образом:

std::string s("Hello world");
upper_print(s);
upper_print(std::string("Hello world"));
upper_print("Hello world"); // converting ctor used

Однако, чтобы избежать избыточности, я хочу использовать ссылку для пересылки:

template <typename T> upper_print(T&& s);

К сожалению, тогда я не могу ссылаться upper_print со строковым литералом:

std::string s("Hello world"); // OK
upper_print(s); // OK
upper_print(std::string("Hello world")); // OK
upper_print("Hello world"); // ERROR

Я знаю о возможности ограничить аргументы std::string объекты, например, с помощью std::enable_if или же static_assert, Но это не помогает здесь.

Есть ли возможность объединить функциональность пересылки ссылок и преобразования конструктора в этом смысле?

1 ответ

Решение

Может быть, такое решение?

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);
}
Другие вопросы по тегам