Передача объекта в качестве аргумента функции по умолчанию по ссылке

Подскажите, пожалуйста, возможно ли реализовать следующий функционал:

У меня есть функция, которая рекурсивно вызывает сама себя и передает себе в качестве параметра вектор, который затем заполняется в теле функции, при этом при первом вызове функции данный параметр не указывается и берется по умолчанию:

void func(int level, std::vector<int> vec = { 0 }) {
    if (level < 0)
        return;

    vec.push_back(level);

    func(level - 1, vec);
}

Я не хотел бы каждый раз создавать новый вектор - это затраты памяти и времени (что более критично), поэтому хотел бы передавать вектор по ссылке:

void func(int level, std::vector<int>& vec = { 0 }) {
...
}

Чтобы это работало, вектор надо делать константным, что меня не устраивает, так как для изменения вектора опять надо делать копирование:

void func(int level, const std::vector<int>& vec = { 0 }) {
    if (level < 0)
        return;

    std::vector<int> vec2(vec);
    vec2.push_back(level);

    func(level - 1, vec2);
}

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

std::vector<int> vec = { 0 };
func(10, vec);

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

Подскажите, можно ли вообще реализовать этот замысел - при первом вызове никакой вектор не указывается, а берется из параметра по умолчанию, а во всех следующих вызовов используется старый вектор без каких-то дополнительных копирований и пересозданий.

P.S.

И не хотелось бы извратов в лоб по типу:

void func(int level, std::vector<int>* vec = new std::vector<int>({ 0 })) {
    if (level < 0)
        return;

    vec->push_back(level);

    func(level - 1, vec);
}

Хотя это, конечно, один из выходов, но как-то по ссылкам работать с объектами приятнее.


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

Автор решения: AR Hovsepyan

Вы хотите создавать объект один раз, и при каждом рекурсивном вызове функции работать именно с этим объектом. Так создайте просто статический объект внутри функции(он и создастся только при первом вызове:

void func(int level) {
    static std::vector<int> vec{ 0 };
    if (level < 0)
        return;
    vec.push_back(level);

    func(level - 1);
}

Но, как верно заметил Andrej Levkovitch, зачем вам этот вектор? Вы не хотите его указывать перед вызовом и не возвращаете из функции. Какую роль он выполняет? Тут или вы сами не ясно объяснили что вам нужно, или другая причина недопонимания...

→ Ссылка
Автор решения: αλεχολυτ

Используйте rvalue ссылку, указав &&. Для этого при рекурсивном вызове придётся добавить std::move:

#include <vector>

void func(int level, std::vector<int>&& vec = {0}) {
    if (level < 0)
        return;

    vec.push_back(level);

    func(level - 1, std::move(vec));
}

int main() {
    func(10);
}
→ Ссылка