Преимущества использования аргумента шаблона функции при простом перемещении параметра - PullRequest
1 голос
/ 19 сентября 2019

Рассмотрим следующую структуру, в которой хранится функция:

struct yyy {
    std::function<int()> myFunc;

    void set_func_1(std::function<int()>&& f) {
        myFunc = std::move(f);
    }

    template<typename funcT>
    void set_func_2(funcT&& f) {
        myFunc = std::move(f);
    }
};

Согласно этому ответу , я знаю, что использование параметра шаблона позволяет компилятору оптимизировать вещи.

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

1 Ответ

3 голосов
/ 19 сентября 2019

&& ссылки, даже если они написаны одинаково, играют разные роли.

void set_func_1(std::function<int()>&& f) {
    myFunc = std::move(f);
}

является правильным, но принимает только ссылки на r-значения.В template<typename funcT> void set_func_2(funcT&& f), && является ссылкой для пересылки , поэтому использование std::move(f) в теле неверно - это может украсть состояние у невременного объекта.Вместо этого вам нужно будет использовать std::forward<funcT>(f).

Преимущество 2-й функции по сравнению с 1-й состоит не в оптимизации.Первый будет принимать только r-значения, поэтому, например, function<int> f = []{return 1;}; struct yyy; yyy.set_func_2(f); не будет компилироваться.

Хороший, простой, почти оптимальный способ написания set() методов - передача по значению и перемещение:

    void set_func_3(std::function<int()> f) {
    myFunc = std::move(f);
}

Книга Скотта Мейерса "Современный эффективный C ++" содержит более подробную информацию о ее применимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...