loop0
loop0

Reputation: 43

c++, what happens when an lvalue is passed to T&&?

#include <bits/stdc++.h>
#include <vector>


template <typename T>
void g(T&& val)
{
    std::vector<T> v;
}

int main()
{
    // g(2);

    int i;
    g(i);
}

When g(2) is called, it complies, but when g(i) is called, the complier has a lot of errors.

Some of the errors are pasted as follows:

forming pointer to reference type ‘int&’

no members matching ‘std::vector<int&, std::allocator<int&> >::_Base {aka std::_Vector_base<int&, std::allocator<int&> >}::_M_allocate’ in ‘std::vector<int&, std::allocator<int&> >::_Base’ {aka ‘struct std::_Vector_base<int&, std::allocator<int&> >’}

no members matching ‘__gnu_cxx::__alloc_traits<std::allocator<int&>, int&>::_Base_type {aka std::allocator_traits<std::allocator<int&> >}::allocate’ in ‘__gnu_cxx::__alloc_traits<std::allocator<int&>, int&>::_Base_type’ {aka ‘struct std::allocator_traits<std::allocator<int&> >’}

forming pointer to reference type ‘int&’

my question:

1. In this case, when the literal value 2 is called, what type is derived for T ?

2. Why doesn't it complie when on i ? How to understand these error messages ?

Upvotes: 4

Views: 82

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

1: A forwarding reference, and

  • g(2) makes T an int
  • g(i) makes T an int&

2: You can't have arrays of references (new T&[x]). You could use std::remove_cvref_t to get the type int out of T:

#include <type_traits>

template <typename T>
void g(T&& val) {
    using type = std::remove_cvref_t<T>; // type is int

    std::vector<type> v;
}

Upvotes: 3

Mansoor
Mansoor

Reputation: 2438

  1. Your universal reference resolves to int for g(2) and int& for g(i)
  2. You can't have a std::vector of a reference type (see this explanation).

Upvotes: 1

Related Questions