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