【问题标题】:Maintain pair element reference type保持对元素参考类型
【发布时间】:2019-05-08 04:28:35
【问题描述】:

有什么方法可以转发一对(或元组)的元素,同时保持其引用类型(例如,继续作为右值)?

下面的示例演示了我的尝试:转发和移动一对(第一个和第二个)的元素,移动对并使用其元素,以及移动对和元素。我希望所有人都能工作,但他们都没有。

template<class T, class U>
auto pair_forward(std::pair<T, U>&& p)
{
    return std::make_pair(std::forward<T>(p.first), std::forward<U>(p.second));
}

template<class T, class U>
auto pair_move_elem(std::pair<T, U>&& p)
{
    return std::make_pair(std::move(p.first), std::move(p.second));
}

template<class T, class U>
auto move_pair(std::pair<T, U>&& p)
{
    return std::make_pair(std::move(p).first, std::move(p).second);
}

int main()
{
    int x;
    std::pair<int, int&&> p(x, std::move(x));
    static_assert(std::is_rvalue_reference<decltype(p.second)>::value); // works

    auto t1 = pair_forward(std::move(p));
    static_assert(std::is_rvalue_reference<decltype(t1.second)>::value); // fails

    auto t2 = pair_move_elem(std::move(p));
    static_assert(std::is_rvalue_reference<decltype(t2.second)>::value); // fails

    auto t3 = move_pair(std::move(p));
    static_assert(std::is_rvalue_reference<decltype(t3.second)>::value); // fails
}

【问题讨论】:

    标签: c++ tuples std-pair


    【解决方案1】:

    make_pair 的推导规则让我很困惑,所以我建议直接用你想要的类型调用构造函数。

    #include <utility>
    
    template<class T, class U>
    auto pair_forward(std::pair<T, U>&& p)
    {
        return std::pair<T, U>(std::forward<T>(p.first), std::forward<U>(p.second));
    }
    
    template<class T, class U>
    auto pair_move_elem(std::pair<T, U>&& p)
    {
        return std::pair<T&&, U&&>(std::move(p.first), std::move(p.second));
    }
    
    template<class T, class U>
    auto move_pair(std::pair<T, U>&& p)
    {
        return std::pair<T, U>(std::move(p));
        // or just: return std::pair(std::move(p));
    }
    
    int main()
    {
        int x;
        std::pair<int, int&&> p(x, std::move(x));
        static_assert(std::is_rvalue_reference<decltype(p.second)>::value); // works
    
        auto t1 = pair_forward(std::move(p));
        static_assert(std::is_rvalue_reference<decltype(t1.second)>::value); // works
    
        auto t2 = pair_move_elem(std::move(p));
        static_assert(std::is_rvalue_reference<decltype(t2.second)>::value); // works
    
        auto t3 = move_pair(std::move(p));
        static_assert(std::is_rvalue_reference<decltype(t3.second)>::value); // works
    }
    

    直播:https://godbolt.org/z/EfGe_x

    【讨论】:

    • 感谢您的回答。你能解释一下为什么make_pair 无法做到这一点吗?还是forward_as_tuple
    • 抱歉,我只记得有时很令人沮丧,而且避免起来更容易。
    • 也许令人沮丧,但这是有原因的。我感觉这里有人知道它是什么。
    猜你喜欢
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 2018-11-22
    相关资源
    最近更新 更多