How to std::forward class template parameter

I’m getting compiler error when using std::forward on a class template parameter, but not on a function template parameter. I’d like to know how to std::forward a class template parameter. This is my code:

#include <iostream>
#include <vector>

template<typename T>
class Data_List {
    std::vector<T> data_list;
    
public:
    Data_List() = default;
    ~Data_List() = default;
    
    std::size_t get_list_size() {
        return data_list.size();
    }
    
    void add_to_list(T&& data) {
        std::cout << "nbefore inside add_to_list: " << data.size() << std::endl;
        data_list.push_back(std::forward<T>(data));
        std::cout << "after inside add_to_list: " << data.size() << std::endl;
    }
};

template<typename T>
void print(T&& t) {
    
}

int main() {
    Data_List<std::vector<int>> list_of_data;

    std::vector<int> data(100, 2);
    std::cout << "n1. before size: " << data.size() << std::endl;
    std::cout << "1. before Data_List size: " << list_of_data.get_list_size() << std::endl;
    print(data);
    // list_of_data.add_to_list(data); // gives compiler error here
    std::cout << "n1. after size: " << data.size() << std::endl;
    std::cout << "1. after Data_List size: " << list_of_data.get_list_size() << std::endl;
    
    std::cout << "--------------------------------------------------------------------------n" << std::endl;
    
    std::cout << "n2. before size: " << data.size() << std::endl;
    std::cout << "2. before Data_List size: " << list_of_data.get_list_size() << std::endl;
    print(std::move(data));
    list_of_data.add_to_list(std::move(data));
    std::cout << "n2. after size: " << data.size() << std::endl;
    std::cout << "2. after Data_List size: " << list_of_data.get_list_size() << std::endl;
    
    std::cout << "--------------------------------------------------------------------------n" << std::endl;
}

This is the error I’m getting cannot bind rvalue reference of type ‘std::vector<int>&&’ to lvalue of type ‘std::vector<int>’

Answer

In here:

void add_to_list(T&& data) {
    std::cout << "nbefore inside add_to_list: " << data.size() << std::endl;
    data_list.push_back(std::forward<T>(data));
    std::cout << "after inside add_to_list: " << data.size() << std::endl;
}

data isn’t a forwarding reference, it’s an rvalue reference, so you can’t do something like list_of_data.add_to_list(data); because data is an lvalue.

To create a forwarding reference, the type must exist as a template parameter of the same function template (Give a reading to the forwarding references part of this cppreference.com page and look specifically at the first example):

  1. function parameter of a function template declared as rvalue reference to cv-unqualified type template parameter of that same function template.

Basically, what you want to do is this:

// ...
template <typename U>
void add_to_list(U&& data) {
    std::cout << "nbefore inside add_to_list: " << data.size() << std::endl;
    data_list.push_back(std::forward<U>(data));
    std::cout << "after inside add_to_list: " << data.size() << std::endl;
}
// ...

Then data becomes a forwarding reference and does what is intended.

Demo