我有一个结构F
和一个函数foo
,无论F
是否是临时,它都有不同的实现
struct F{
void foo() & { std::cout << "F::foo() &" << std::endl; }
void foo() && { std::cout << "F::foo() &&" << std::endl; }
};
另一个结构体A
具有F
的副本,并且在其函数bar
中调用F::foo
。我想使用正确版本的F::foo()
。因此,实现是:
struct A{
void bar() & {
f.foo();
}
void bar() && {
std::move(f).foo();
}
F f;
};
我想知道我是否真的必须提供A::bar()
的两个实现。有没有一种聪明的方法可以使用std::forward
来自动决定应该使用哪个F::foo()
?
尝试:
struct B{
void bar() {
std::forward<F>(f).foo();
}
F f;
};
然而,这是行不通的。它每次调用F::foo() &&
。
完整示例
您可以使用非成员函数模板:
struct B{
template<typename TB>
friend void bar(TB&& self) {
std::forward<TB>(self).f.foo();
}
F f;
};
根据其他函数参数,您可能希望限制TB
的类型,使其成为is_base_of_v<B, remove_const_t<remove_reference_t<TB>>>
。
不,目前没有可用的快捷方式,您需要坚持使用详细版本。但是看看p0847,";推导出CCD_ 15";。然而,我不确定这项提议的现状。摘自摘要:
我们提出了一种新的机制来指定或推导类实例的值类别。换句话说,这是一种从成员函数内部判断其调用对象是左值还是右值,以及它是常量还是可变值的方法。