【问题标题】:Storing a C++20 function-like object from a forwarding reference?从转发引用中存储类似 C++20 函数的对象?
【发布时间】:2021-05-26 14:03:41
【问题描述】:

在 C++20 中,假设我想要 std::make_unique 一个副本(或酌情移动)并存储一个在转发引用中传递的类似函数的对象...

template<typename F>
std::unique_ptr<???> make_copy_of_functor(F&& f) {
    return std::make_unique<???>(std::forward<F>(f));
}

???s 中有什么内容?将F放在那里是否正确...

template<typename F>
std::unique_ptr<F> make_copy_of_functor(F&& f) {
    return std::make_unique<F>(std::forward<F>(f));
}

或者我需要以某种方式衰减它吗? (我可能对转发引用的引用折叠规则感到困惑。)

【问题讨论】:

    标签: c++ c++20


    【解决方案1】:

    作为转发引用,当被传递左值F会被推导出为左值引用,你可以使用std::decay删除引用部分(并为函数类型添加指针)。

    template<typename F>
    auto make_copy_of_functor(F&& f) {
        return std::make_unique<std::decay_t<F>>(std::forward<F>(f));
    }
    

    【讨论】:

    • 实际上我得到error: new cannot be applied to a function type 在普通函数上使用时,我猜转发引用是对函数的引用,而不是应用函数到指针的标准转换。如果我使用 make_copy_of_functor(&my_function) 它可以工作。
    • 也许std::decay 更好? en.cppreference.com/w/cpp/types/decay不确定。
    • @AndrewTomazos 是的,我们需要明确地将F 设为函数指针类型; make_copy_of_functor(&amp;my_function) 就是这样做的。是的,std::decay 似乎更好。
    • 是的,如果我们使用std::decay,那么make_copy_of_functor(my_function) 可以工作(没有&amp;)。
    【解决方案2】:

    你可以通过值传递,然后移动到一个新的对象中:

    template <typename F>
    auto make_copy_of_functor(F f) {
      return std::make_unique<F>(std::move(f));
    }
    

    【讨论】:

    • 与其他解决方案相比,这不是双重举措吗?一个移动到函数参数,然后另一个移动到构造函数?还是其中一个被省略了?
    • 是的。如果您通过右值传递,这将调用两个移动操作,否则将调用一个复制操作和一个移动。但是移动操作很便宜,而且这段代码看起来更整洁(可能不太容易出错)。
    猜你喜欢
    • 2018-03-19
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多