繁体   English   中英

“模板化右值引用”而不是通用引用作为参数?

[英]"Templated rvalue-reference" instead of universal reference as parameter?

我有一个类对象,它采用受限于某个概念的通用参数。 现在我想将此参数(哪种类型仍然未知)转发给适合此引用类型的construct重载:根据转发的参数选择 rvalue-ref 重载或 const ref 重载。 我怎样才能做到这一点?

问题是,一旦我放入双符号,“模板右值引用”就变成了通用引用,我看不出有什么方法可以规避它。 下面的示例表明,在这两种情况下都选择了“贪婪”的通用 ref 重载,即使我希望第一个实例化与 const ref 一起使用。

演示

#include <concepts>
#include <cstdio>
#include <utility>

template <typename... Args>
struct function
{
    template <std::invocable<Args...> Cb>
    function(Cb&& fn) {
        construct(std::forward<Cb>(fn));
    }

    template<typename Cb>
    auto construct(const Cb&) {
        printf("Overload for const-ref called!\n");
    }

    template <typename Cb>
    auto construct(Cb&&) {
        printf("Overload for rvalue-ref called!\n");
    }
};

struct functor
{
    auto operator()()
    {
        printf("Functor called!\n");
    }
};

int main()
{
    functor foo1;

    function myfunc{foo1};
    function myfunc2{functor{}};
}

输出:

Overload for rvalue-ref called!
Overload for rvalue-ref called!

更新

由于上述案例可能已经过于做作,无法真正展示我正在尝试的内容,您可以在此处找到更详细的示例。

主要的答案是你应该尽量不要这样做,因为通常没有充分的理由执行这种重载决议。 当你有一个具体类型时,有一个采用左值引用的重载和一个采用右值引用的重载是有意义的,因为只有后者有权从其参数中掠夺资源。 但是一个说“我接受任何东西,但它必须过期”的函数模板通常不能对它的参数即将过期的信息做任何有用的事情,除了最终将它转发给一个采用具体类型的重载。

然而,这是可能的。 一种方法是:

template <typename Cb>
auto construct(Cb&&) requires(!std::is_reference_v<Cb>) {
    printf("Overload for rvalue-ref called!\n");
}

这使用了这样一个事实,如果转发引用的参数是左值,则模板参数被推导为左值引用,但如果参数是右值,则模板参数被推导为引用类型(即非引用).

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM