我知道以下功能
template <typename T>
void do_something(T&& arg);
function参数是转发引用。但在以下情况下,它仍然是转发引用或右值引用吗?
template <typename T>
class MyClass
{
void do_something(T&& arg);
};
我认为它仍然是转发参考,但我不确定。此外,我想知道,如果结果不是我想要的,可以采取什么措施来强制执行右值引用或转发引用。
答案 0 :(得分:6)
这是一个右值参考。转发引用只能出现在推断的上下文中。这只是一个成员函数,它接受对类模板参数的右值引用。
如果要维护函数的模板参数推导,则不能强制转发引用为右值引用。如果你不介意在整个地方指定模板参数,那么这将始终只给出一个右值引用:
template<typename T> struct identity { using type = T; };
template <typename T> void func(typename identity<T>::type&&);
回想起来,实际上有一种方法可以保持演绎,但强制只接受右值引用(除了Simple的答案中的自我记录)。您可以提供已删除的左值超载:
template<typename T>
void func(T&) = delete;
template<typename T>
void func(T&& s)
{
// ...
}
传递左值时,左值超载更加专业化。并且由于被删除,将给出一些有些明确的错误消息。
答案 1 :(得分:3)
此外,我想知道如何强制执行右值参考
如果您总是希望在推导的上下文中使用右值引用(而不是转发引用),那么您可以使用:
template<
typename T,
typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>
>
using rval_ref = T&&;
template<typename T>
void foo(rval_ref<T> s)
{
// ...
}
foo
只能使用右值调用,而T
不会作为参考(即如果您使用foo
致电std::string&&
,则T
将是std::string
)。