Желаемое поведение
Я хочу создать такую функцию:
void func(std::string_view... args)
{
(std::cout << ... << args);
}
Она должна работать только с классами, которые можно преобразовать.на std::string_view
.
Пример:
int main()
{
const char* tmp1 = "Hello ";
const std::string tmp2 = "World";
const std::string_view tmp3 = "!";
func(tmp1, tmp2, tmp3, "\n");
return 0;
}
должен вывести: Hello World!
Завершенное поведение
Пока что я получилздесь:
template<typename... types>
using are_strings = std::conjunction<std::is_convertible<types, std::string_view>...>;
template<typename... strings, class = std::enable_if_t<are_strings<strings...>::value, void>>
void func(strings... args)
{
(std::cout << ... << args);
}
int main()
{
const char* tmp1 = "Hello ";
const std::string tmp2 = "World";
const std::string_view tmp3 = "!";
func(tmp1, tmp2, tmp3, "\n");
return 0;
}
Это на самом деле работает, как и ожидалось, но есть еще одна большая проблема.
Задача
В этой функции можно использовать только классы, конвертируемые в std::string_view
, и это здорово.
Однако, даже если классы конвертируемы, они не конвертируется в std::string_view
!
Это приводит к ненужному копированию данных (например, когда std::string
передается в качестве аргумента).
Вопрос
Существует ли способ принудительного неявного преобразования аргументов переменной в std::string_view
?
Примечание
Я знаюо std::initializer_list
, но я бы хотел, чтобы вызов функции был простым, без {}
.