Question: I would like to use a universal reference with vector.

```
template<typename T>
    void foo(T&& v)
    {
        for(typename T::iterator i = v.begin(); i != v.end(); i++)
        {
            std::cout << *i << std::endl;
        }
    }

int main()
{
    std::vector v = {0,5,4,3};
    foo(std::move(v));
    foo(v); //compiler error
    return 0;
}

```

but when I use as argument of foo function v(without std::move) it cause a compiler error.

I think that in both case universal reference should work. 

Error:

```
prog.cc: In instantiation of 'void foo(T&&) [with T = std::vector<int, std::allocator<int> >&]':
prog.cc:25:10: required from here prog.cc:16:30: error: 'std::vector<int, std::allocator<int> >&' is not a class, struct, or union type 16 | for(typename T::iterator i = v.begin(); i != v.end(); i++) | ^
prog.cc:16:30: error: 'std::vector<int, std::allocator<int> >&' is not a class, struct, or union type 

```

Answer: 
When you pass an *lvalue* to `foo`, `T` is deduced as an *lvalue reference* due to special perfect forwarding rules:

> 
> From [[temp.deduct.call]](http://eel.is/c++draft/temp.deduct.call#def:forwarding_reference) (12.9.2.1 par 3):
> 
> 
> 
> > 
> > A forwarding reference is an rvalue reference to a cv-unqualified template parameter that does not represent a template parameter of a class template (during class template argument deduction ([over.match.class.deduct])). **If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction.**
> > 
> > 
> > 
> 
> 
> 

Therefore `typename T::iterator` will attempt to access the `iterator` type alias of an *lvalue reference*, which does not exist.

You can either change it to:

```
typename std::remove_reference_t<T>::iterator

```

Or simply:

```
for(auto i = v.begin(); i != v.end(); i++) { /* ... */ }

```

Or even better:

```
for(const auto& x : v) { std::cout << x << '\n'; }

```
The issue is the explicit loop:

```
for(typename T::iterator i = v.begin(); i != v.end(); i++)

```

where `T` is replaced by type the template is instantiated with. For an rvalue reference, this is `T` (and the function argument is an rvalue reference), for an lvalue-reference, it is `T&` (and due to reference collapsing, the function argument is an lvalue reference). The line above hence tries something like `typename T&::iterator i` which does not work. One way to fix this is e.g.

```
for(typename std::decay_t<T>::iterator i = v.begin(); i != v.end(); i++)

```

But the function template is also a nice demonstration of the declarative power of range based for loops, as this works for both cases without any manual removal of references:

```
for (auto& i : v)
   std::cout << i << "\n";

```