Как избежать создания копии строки при передаче аргумента параметру функции, а также избежать использование кучи?

Задача связана с реализацией протокола обмена сообщениями. Функции std::vector<uint8_t> make_buff(const msg_t& msg); передается объект с двумя полями - имя и текст сообщения. Далее, функция make_buff() в зависимости от длины текста сообщения начинает паковать данные по пакетам:

std::vector<uint8_t> make_buff(const msg_t& msg) {
    std::string nm  = msg.name;
    std::string txt = msg.text;

    // .....

    std::vector<uint8_t> buff;

    if (txt.size() > MSG_MAXLEN) { // if greater than 31 symbols
        packMultStrData(nm, txt, buff);
        return buff;
    } else {
        packdata(nm, txt, buff);
        return buff;
    }

Для этого написаны следующие функции:

void packdata(std::string& name, std::string text, std::vector<uint8_t>& buff) {

    uint8_t firstByte = FLAG_MASK; // -96
    firstByte = firstByte + name.length() * 2;

    std::bitset<8> fB1{ firstByte };
    dbg_out << "\nFirst  byte: " << std::setw(25) << fB1.to_string() << std::endl;

    if (text.length() > 15) {
        firstByte = firstByte + 1;
        std::bitset<8> fB2{ firstByte };
        dbg_out << "The first byte was changed: " << std::setw(10) << fB2.to_string() << std::endl;
    }

    buff.push_back(firstByte);
    uint8_t secondByte = (text.length()) << 4;
    std::bitset<8> sB1{ secondByte };
    dbg_out << "Second byte: " << std::setw(25) << sB1.to_string() << std::endl;

    std::vector<unsigned char> controlledString;

    controlledString.push_back(FLAG); // 5
    controlledString.push_back(name.length());
    controlledString.push_back(text.length());
    controlledString.insert(controlledString.end(), name.begin(), name.end());
    controlledString.insert(controlledString.end(), text.begin(), text.end());

    std::uint8_t CRC4 = crc4itu(0x00, controlledString, controlledString.size());

    std::bitset<8> crc4{ CRC4 };
    dbg_out << "CRC4   value: " << std::setw(24) << crc4.to_string() << std::endl;

    secondByte = secondByte + CRC4;

    std::bitset<8> sB2{ secondByte };
    dbg_out << "Second byte with CRC4 value: " << std::setw(9) << sB2.to_string() << std::endl;

    buff.push_back(secondByte);

    for (int i = 0; i < name.length(); ++i) {
        buff.push_back(name[i]);
    }

    for (int i = 0; i < text.length(); ++i) {
        buff.push_back(text[i]);
    }

    dbg_out << "\nBuffer size: " << buff.size() << std::endl << std::endl;
}
void packMultStrData(std::string& name, std::string& txt, std::vector<uint8_t>& buff) {

    std::vector<uint8_t> vtemp;

    for (int i = 0; i < txt.length(); ++i) {
        vtemp.push_back(txt[i]);

        if (vtemp.size() == MSG_MAXLEN) {
            packdata(name, std::string(vtemp.begin(), vtemp.end()), buff);
            vtemp.clear();
        }

        if (txt.length() - i == 1) {
            packdata(name, std::string(vtemp.begin(), vtemp.end()), buff);
        }
    }
}

Как можно переписать код так, чтобы можно было избежать копирования строки при передаче аргумента параметру text, а также избежать использование кучи при вызове packdata(name, std::string(vtemp.begin(), vtemp.end()), buff)? Возможно ли создание одной функции вместо двух packdata() и packMultStrData()?


Ответы (1 шт):

Автор решения: Eugene X

Передать константу на refernce твоей строки.

И да именно константу! Что-бы не сломать оригинальную строку.

void my_function(const std::string & mystring) {}
→ Ссылка