Ответы пользователя по тегу C++
  • Зачем std::forward иметь две сигнатуры и явно указывать тип?

    makarenya
    @makarenya
    программист
    Попытка №2, в первой был бред:
    Основной проблемой является то, что внутри метода все параметры имеют тип l-value. То есть модификатор параметра && - это лишь требование, чтобы на место этого аргумента вызывающий код передал r-value (а для шаблонов даже этого не требует, благодаря склейки ссылок). И раз так, то ваш метод my_forward переделает вернёт l-value ссылки вообще для всех аргументов.

    Отсюда берётся необходимость явно указывать тип аргумента - чтобы использовался именно выведенный тип, а не l-value на этот тип. Ну и почему 2 специализации: если указать явно тип аргумента и явно специализировать функцию каким-нибудь r-value, то my_forward будет ожидать строго r-value, и являющееся l-value значение параметра туда не подойдёт.

    В объяснение моих мыслей, код
    #include <iostream>
    
    template<typename T>
    decltype(auto) my_forward(T&& arg)
    {
        return static_cast<T&&>(arg);
    }
    
    template <typename T, typename K>
    void forward(T&& t, K&& k)
    {
        std::cout << std::is_same<int&&, decltype(my_forward(t))>::value << std::endl;
        std::cout << std::is_same<int&, decltype(my_forward(k))>::value << std::endl;
        std::cout << std::is_same<int&&, decltype(std::forward<T>(t))>::value << std::endl;
        std::cout << std::is_same<int&, decltype(std::forward<K>(t))>::value << std::endl;
    }
    
    int main()
    {
        int lval = 10;
        forward(10, lval);
        return 0;
    }


    вернёт
    0
    1
    1
    1

    То есть предположение что my_forward вернуло int&& для первого параметра - не верно!
    Ответ написан
    4 комментария