1

Here is a subset of my code. Why can't it bind a const int to an rvalue reference? What I expect is that T will be deduced as int const & and the type of e as int const & && will be folded to int const &.

template <typename T>
List<T>::List(initializer_list<T> il)
{
    for (T const & i : il) insertAsLast(i);
}

template <typename T>
ListNode<T> * List<T>::insertAsLast(T && e)
{
    ++_size; return trailer->insertAsPrev(std::forward<T>(e));
}

template <typename T>
ListNode<T> * ListNode<T>::insertAsPrev(T && e)
{
    pnode node = new ListNode<T>(std::forward<T>(e), prev, this);
    prev->next = node; prev = node;
    return node;
}

int main()
{
    List<int> l = {1, 3, 2, 1, 34, 5, 2, 34, , 4};
}

error:

can't bind a const int to a rvalue reference

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
BAKE ZQ
  • 765
  • 6
  • 22

1 Answers1

3

and the type of e int const & && will be folded to int const &.

No, here's no reference collapsing. T && becomes forwarding reference only when it's the template parameter of the function template, but T seems to be the template parameter of the class template List; then T&& is just the rvalue-reference here.

Making List<T>::insertAsLast template would solve the problem, but whether it's the correct solution depends on your design.

template <typename T>
template <typename X>
ListNode<T> * List<T>::insertAsLast(X && e)
{
    ++_size; return trailer->insertAsPrev(std::forward<X>(e));
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • I followed your suggestion. and now I meet another problem. – BAKE ZQ Apr 12 '19 at 05:08
  • 1
    @BAKEZQ If this answer addressed the initial issue you were having, make sure to mark it as "accepted" by clicking the check mark. If you have another problem, you should create a new question for it, rather than reusing this one. – Sneftel Apr 12 '19 at 05:12