C++ 完美转发

C++ 完美转发,c++,c++11,forwarding,decltype,C++,C++11,Forwarding,Decltype,如果我们具备以下条件: template <class T> struct B{ T data; } struct A{ int data_array[100]; } int main() { A x; const A x_const; auto y1 = f(A()); auto y2 = f(x); auto y3 = f(x_const); auto y4 = f(std::move(x)); } 也就是说,f完美地将x转发到B模板的对象

如果我们具备以下条件:

template <class T>
struct B{
  T data;
}

struct A{
  int data_array[100];
}

int main()
{
  A x;
  const A x_const;

  auto y1 = f(A());
  auto y2 = f(x);
  auto y3 = f(x_const);
  auto y4 = f(std::move(x));
}
也就是说,
f
完美地将
x
转发到
B

模板的对象中
template <typename T>
auto f(T&& t) -> B<decltype(std::forward<T>(t))>
{
    return B<decltype(std::forward<T>(t))>{std::forward<T>(t)};
}
自动f(T&T)->B { 返回B{std::forward(t)}; }

这几乎是你想要的。唯一的区别是第一种类型是
B
而不是
B

这是不可能的。对于
y1
y4
,它们都接受类型为A的右值,但您希望它们返回不同的类型。
f
如何知道返回什么

template <typename T>
auto f(T&& t) -> B<decltype(std::forward<T>(t))>
{
    return B<decltype(std::forward<T>(t))>{std::forward<T>(t)};
}
auto y1 = f(A());
auto y4 = f(std::move(x));

将无法区分,因为
A()
会生成一个临时变量,该变量将绑定到
A&&

您可以选择函数重载作为最后手段。:)嗯,
decltype(A())
A
,但是
decltype(std::move(A())
A&
,所以有一些不同。@HighCommander4:它们都是右值。没有任何引用或其他语言结构可以区分A和未命名的A&&-事实上,有一半是不能区分的。@HighCommander4问题的区别在于一个是prvalue,另一个是xvalue。由于参数传递只允许区分左值和右值,因此确实不可能检测函数内部的差异(这是通过设计实现的)。