Использование временного объекта без сохранения его в переменной - PullRequest
4 голосов
/ 14 июля 2020

Давайте рассмотрим пример, в котором нам нужно вставить вектор, возвращенный функцией, в другой вектор:

const std::vector<int> getvec(){
    return {1, 2, 3};
}

// in main...
std::vector<int> foo{ 11, 12 };
auto bar = getvec();
foo.insert(foo.end(), bar.begin(), bar.end());

Тот факт, что на переменную bar необходимо дважды ссылаться в методе insert() делает необходимым хранить вектор как переменную (иначе мы могли бы сделать foo.myinsert(getvec()), если бы был такой интерфейс).

Меня немного раздражает, что в таком случае нам нужно ввести переменная foo в основной области видимости, которая не предназначена для повторного использования в остальной части кода, поскольку она занимает память и загрязняет пространство имен. Особенно проблема, если мы говорим о большом «временном» объекте.

Есть ли стандартный подход к этому? Мы могли бы определить функцию, которая принимает «временный» объект только один раз, чтобы мы могли напрямую передавать ему выходные данные функции, но было бы трудно управлять, если бы нам нужно было определять такую ​​функцию для каждого подобного сценария. Также, как и в этом примере, мы не можем определить функцию-член для класса vector.

В качестве альтернативы, что использовать фигурные скобки для ограничения объема «временной» части вставки, но я хотел бы знать, любые оговорки здесь.

vector<int> foo{ 11, 12 };
{ // extra brace here
    auto bar = getvec();
    foo.insert(foo.end(), bar.begin(), bar.end());
} // extra brace here

Ответы [ 3 ]

2 голосов
/ 14 июля 2020

Для этого вы можете написать небольшую шаблонную функцию, которая принимает вектор по константной ссылке (которая может привязываться к временной и продлевать время ее жизни): другие типы векторов. Тогда вы можете называть это так:

append(foo, getvec());

Рабочая демонстрация здесь .

2 голосов
/ 14 июля 2020

Не самое красивое решение, но вы можете использовать временную лямбду вместо отдельной функции, а объявление и вызов ее в том же операторе избавляет от необходимости использовать фигурные скобки для ограничения области действия.

const std::vector<int> getvec(){
    return {1, 2, 3};
}

// in main...
std::vector<int> foo{ 11, 12 };
[&](const auto &bar){ foo.insert(foo.end(), bar.begin(), bar.end()); }(getvec());

Live Demo

0 голосов
/ 14 июля 2020

Вы можете создавать строки из других вещей, кроме char. Через basic_string<int> вы можете получить доступ к string::append (и другим вещам)

using strint = std::basic_string<int>;
strint getVec () {
    return { 1, 2, 3, 4, 5 };
}

strint foo{ 6, 7 };
foo += getVec();

https://godbolt.org/z/h4naTa

...