Как перегрузить функции манипулирования строкой и копированием строк?

Я хотел бы иметь возможность сделать следующее:

std::cout << str_manip("string to manipulate");

так же как

std::string str;
str_manip(str);
std::cout << str;

Для этого у меня есть две функции

#include <string>

// copying
std::string str_manip(std::string str)
{
// manipulate str
return str;
}

// in-place
void str_manip(std::string& str)
{
// manipulate str
}

но они выдают следующую ошибку:

error: call of overloaded 'str_manip(std::__cxx11::string&)' is ambiguous

Как я могу преодолеть это?

0

Решение

Проблема с этим вызовом:

std::string str;
str_manip(str);
std::cout << str;

Компилятор не знает, какая версия str_manip звонить.

Вы можете изменить свои функции так:

#include <string>

// copying
std::string str_manip(const std::string& str)
{
std::string dup = str;
// manipulate dup
return dup;
}

// in-place
void str_manip(std::string& str)
{
// manipulate str
}

Теперь компилятор знает, что неоднозначный вызов должен быть функцией, которая принимает неconst параметр. Вы также можете быть уверены, что ваш звонок, который возвращает std::string к << Оператор не изменяет вашу строку.

1

Другие решения

Это может быть не то, что вы ищете, а ваш код

std::cout << str_manip("string to manipulate");

параметр для str_manip это не string но const char* (на самом деле массив, но конвертируемый в char указатель). Вы можете перегрузить, основываясь на этом.

std::string str_manip(const char* s)
{
std::string str(s); // create str
// manipulate str
return str;
}

Однако давайте посмотрим на общую картину. Когда ты видишь str_manip в вашем коде это означает «изменить строку» или «создать новую строку на основе заданной строки»? Хотите ли вы быть намеренно амбивалентным по отношению к реальному смыслу?

Считайте, что вы читаете свой код через 1 год в будущем. Что вы будете думать, когда увидите звонок str_manip — это мутирует свой параметр? Зависит ли ответ на предыдущий вопрос от контекста?

Цель написания кода — прояснить его, особенно в многопарадигмальном языке, таком как C ++. Так что, на мой взгляд, просто не перегружайте то, о чем вы думаете. Вместо этого сделайте 2 разных имени, например

void frobnicate_str(std::string&) {...}
std::string get_frobnicated_str(std::string) {...}
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector