[英]"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.