Bin Packing Algorithms in C++

This code implements both the First-Fit algorithm (from A-Level Further Decision) amd the First-Fit-Decreasing algorithm.

The First-Fit decreasing algorithm also relies on a sorting algorithm, for this, I implemented the Bubble Sort (warning, this has an O(n^2) difficulty, not for production workplaces)

Virtually the whole main() function can be ignore if you are going to use the different classes and functions that I've written here!

    
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Obj
{
public:
    int size = 0;
    std::string name = "0";
    explicit Obj() {}
    explicit Obj(int size, std::string name)
    {
        this->size = size;
        this->name = name;
    }
};

class Bin
{
public:
    int capacity = 0;
    int total_used = 0;
    vector<Obj> objects = std::vector<Obj>(0);

    explicit Bin() {}

    explicit Bin(int capacity)
    {
        this->capacity = capacity;
        this->total_used = 0;
    }

    template <typename T>
    bool RoomFor(T obj)
    {
        if (total_used + obj.size <= capacity)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    bool RoomForInt(int obj)
    {
        if (total_used + obj <= capacity)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    template <typename T>
    void Append(T obj)
    {
        if (!this->RoomFor(obj))
        {
            throw std::invalid_argument("No room left in bin.");
        }

        if (typeid(T) == typeid(int))
        {
            Obj temp_Obj = Obj(obj);
            this->objects.push_back(obj);
        }
        else if (typeid(T) == typeid(obj))
        {
            this->objects.push_back(obj);
        }
    }

    friend auto operator<<(std::ostream &os, Bin const &b) -> std::ostream &
    {
        std::string rtstring = "";
        for (int i = 0; i < b.objects.size(); i++)
        {
            if (i != 0)
            {
                rtstring += ", ";
            }
            rtstring += b.objects[i].name;
        }

        return os << rtstring;
    }
};

float lowerBound(vector<Obj> objs, int bin_size)
{
    int sum = 0;
    for (int i = 0; i < bin_size; i++)
    {
        sum += objs[i].size;
    }
    return (float)sum / (float)bin_size;
}

void FirstFitFunctioning(vector<Obj> objs, vector<Bin> bins)
{
    bool appended = false;
    for (int i = 0; i < objs.size(); i++)
    {
        appended = false;
        std::cout << objs[i].size << std::endl;
        for (int j = 0; j < bins.size(); j++)
        {
            if (bins[j].RoomFor(objs[i]))
            {
                appended = true;
                bins[j].Append(objs[i]);
                break;
            }
        }
        if (appended == false)
        {
            throw std::invalid_argument("ERROR COULDNT FIT");
        }
    }

    for (int i = 0; i < bins.size(); i++)
    {
        std::cout << i << ": " << bins[i] << std::endl;
    }
}

vector<Obj> ReOrder(vector<Obj> objs)
{
    bool sorted = false;
    int swapped = 0;
    while (!sorted)
    {
        sorted = false;
        swapped = 0;
        for (int i = 0; i < objs.size() - 1; i++)
        {
            if (objs[i].size < objs[i + 1].size)
            {
                swapped += 1;
                swap(objs[i], objs[i + 1]);
            }
        }
        if (swapped == 0)
        {
            sorted = true;
        }
    }
    return objs;
}

void FirstFitDecreasingFunctioning(vector<Obj> objs, vector<Bin> bins)
{
    objs = ReOrder(objs);
    FirstFitFunctioning(objs, bins);
}

int main()
{
    std::cout << "Hello World" << std::endl;
    std::cout << "How many objects do you have? ";
    int num_objs;
    std::cin >> num_objs;
    std::cout << std::endl;
    int temp_size;
    std::string temp_size_str;
    std::string temp_str_name;
    vector<Obj> objects = std::vector<Obj>(0);
    for (int i = 0; i < num_objs; i++)
    {
        std::cout << i << ": ";
        std::cin.ignore();
        std::getline(std::cin, temp_str_name);
        if (temp_str_name.empty())
        {
            temp_str_name = std::to_string(i);
        }

        std::cout << i << " size: ";
        std::getline(std::cin, temp_size_str);
        // https://www.systutorials.com/how-to-remove-newline-characters-from-a-string-in-c/
        temp_size_str.erase(std::remove(temp_size_str.begin(), temp_size_str.end(), '\n'), temp_size_str.end());
        temp_size = std::stoi(temp_size_str);

        objects.push_back(Obj(temp_size, temp_str_name));
    }

    std::cout << "How many bins do you have? ";
    std::string bin_num_str;
    std::getline(std::cin, bin_num_str);
    int bin_num;
    bin_num = std::stoi(bin_num_str);

    std::cout << "How big are the bins? ";
    std::string bin_size_str;
    std::getline(std::cin, bin_size_str);
    int bin_size;
    bin_size = std::stoi(bin_size_str);

    vector<Bin> bins = std::vector<Bin>(0);
    for (int i = 0; i < bin_num; i++)
    {
        bins.push_back(Bin(bin_size));
    }

    std::cout << "Total Capacity: " << bin_size * bin_num << std::endl;
    std::cout << "Lower Bound: " << lowerBound(objects, bin_size) << std::endl;

    std::cout << "First Fit: " << std::endl;

    FirstFitFunctioning(objects, bins);

    std::cout << "First Fit: " << std::endl;
    FirstFitDecreasingFunctioning(objects, bins);

    return 0;
}