Как перегрузить функции манипулирования строкой и копированием строк? - PullRequest
0 голосов
/ 13 ноября 2018

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

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

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

Ответы [ 2 ]

0 голосов
/ 13 ноября 2018

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

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 в своем коде, означает ли это «изменить строку» или «создать новую строку на основе данной строки»?Хотите ли вы быть намеренно амбивалентным в отношении реального значения?

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

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

void frobnicate_str(std::string&) {...}
std::string get_frobnicated_str(std::string) {...}
0 голосов
/ 13 ноября 2018

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

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 оператору <<, не изменяет вашу строку.

...