Question: I got confused by the following perfect forwarding function, where the template parameter `T` can match rvalue or lvalue references:

```
template<typename T>
void foo(T&& t){
    T::A; // intended error to inspect type
}

int main(){
    std::vector<int> a;
    std::vector<int> && b = std::move(a);

    foo(b);             // T is std::vector<int> & 
    foo(std::move(a));  // T is std::vector<int>
}

```

I dont understand why the template argument deduction of `T` in `foo` is so different in these two cases? Whats the fundamental difference and important what is `t`'s type in function `foo`.

`std::move(a)` returns a rvalue reference and `b` is already a rvalue reference (but has a name).

Is that right that, `b` s type is a rvalue reference to `std::vector<int>`, but as far as my understanding goes, it has a name and is thus considered an lvalue in function main?

Can anyone shine some light into this :-)

Answer: 
There is a special type deduction rule when && is used with templates.

```
template <class T>
void func(T&& t) {
}

```

> 
> "When && appears in a type-deducing context, T&& acquires a special
>  meaning. When func is instantiated, T depends on whether the argument
>  passed to func is an lvalue or an rvalue. If it's an lvalue of type U,
>  T is deduced to U&. If it's an rvalue, T is deduced to U:"
> 
> 
> 

```
func(4);            // 4 is an rvalue: T deduced to int

double d = 3.14;
func(d);            // d is an lvalue; T deduced to double&

float f() {...}
func(f());          // f() is an rvalue; T deduced to float

int bar(int i) {
  func(i);          // i is an lvalue; T deduced to int&
}

```

Also, reference collapsing rule is a good read.

Check this out for a really good explanation:

[perfect forwarding](http://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c/)
If you think about the signature of your function, the type of the parameter is `T&&`. In your second example, `T` is deduced to `vector<int>`, that means that the type of the parameter to your function is `vector<int>&&`. So you are still passing by (rvalue) reference.

In the other case, you deduce `T` to `vector<int>&`. So the type of the argument is `vector<int> & &&`... or it would be, but references to references are not allowed. Reference collapsing takes over, and any double reference involving an lvalue reference become an lvalue reference. So you are passing by lvalue reference.

As far as b goes, this is a well known gotcha of rvalue references. Essentially, b's type is rvalue reference, but b itself still has a value category of lvalue. Think of it this way: b itself is a variable, that must live on the stack somewhere, and have an address. So it's an lvalue. This is precisely way calling std::forward when forwarding arguments is necessary. If you didn't do it, then they would always be forwarded as lvalue arguments.

I really recommend this Scott Meyers article: <https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers>. Read it carefully!