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/)
The *expressions* `a` and `b` are both lvalues, and the expression `std::move(a)` is an rvalue.

The deduction for the parameter `T` makes use of special reference collapsing rules so that the type of `t` is either an lvalue or an rvalue reference as needed to bind to the function call argument.