有没有办法定义一个只处理xvalue或prvalue的函数(或者这里是一个独占的)?
例如,假设我有一个方法f(foo&& f)
,如何声明f
绑定xvalue类型并拒绝prvalue类型,反之亦然?
struct Foo{};
void xvalue(/*what put here ?*/){}
void prvalue(/*what put here ?*/){}
void main()
{
Foo foo;
prvalue(Foo());//compile
prvalue(std::move(foo)));//fail at compilation
xvalue(std::move(foo)); //compile
xvalue(Foo());//fail at compilation
}
也许通过使用std::enable_if
以及decltype(e)是xvalues的右值引用类型和prvalue的非引用类型这一事实?
答案 0 :(得分:2)
使用此answer中的代码,这应该是微不足道的。
#include <type_traits>
#include <iostream>
#include <utility>
template <typename T>
bool is_xvalue()
{
if (std::is_lvalue_reference<T>::value)
return false;
else if (std::is_rvalue_reference<T>::value)
return true;
return false;
}
template <typename T>
bool is_prvalue()
{
if (std::is_lvalue_reference<T>::value)
return false;
else if (std::is_rvalue_reference<T>::value)
return false;
else
return true;
return false;
}
struct Foo {};
int main()
{
std::cout << std::boolalpha;
std::cout << is_prvalue<decltype(Foo())>() << "\n"; // true
std::cout << is_prvalue<decltype(std::move(Foo()))>() << "\n"; // false
std::cout << is_xvalue<decltype(Foo())>() << "\n"; // false
std::cout << is_xvalue<decltype(std::move(Foo()))>() << "\n"; // true
return 0;
}
不幸的是,您必须明确地实例化模板,否则它由于某种原因不起作用。
struct Foo {};
template <typename T, typename = typename std::enable_if<is_prvalue<T>(), void>::type>
void prvalue(T&& t)
{
}
template <typename T, typename = typename std::enable_if<is_xvalue<T>(), void>::type>
void xvalue(T&& t)
{
}
prvalue<decltype(Foo())>(Foo());
// prvalue<decltype(std::move(Foo()))>(std::move(Foo())); - compile error
xvalue<decltype(std::move(Foo()))>(std::move(Foo()));
// xvalue<decltype(Foo())>(Foo()); - compile error