'Different types together in std::vector

Summary of the problem:

Goal: Storing pointer data types(including primary, derived and user-defined) in a vector and freeing the memory safely. So, at n index, it may be either float or class(pointer). That's the question.

Additionally, I'm not sure exactly whether std::variant is the best option or not. So, I'd be happy if you could also answer that is there any better solution other thanstd::variant such as template or something else? And if the best solution is std::variant, how can I free up memory safely/correctly?

Here's my try:

#include <iostream>
#include <memory>
#include <string>
#include <stdexcept>
#include <vector>
#include <variant>

namespace _
{
    template<typename ... Args>
    std::string string_format(const std::string& format, Args ... args)
    {
        int size_s = std::snprintf(nullptr, 0, format.c_str(), args ...) + 1;
        auto size = static_cast<size_t>(size_s);
        std::unique_ptr<char[]> buf(new char[size]);
        std::snprintf(buf.get(), size, format.c_str(), args ...);
        return std::string(buf.get(), buf.get() + size - 1);
    }
};// don't mind this

class Foo
{
public:
    Foo() {};

    const int var = 10;
};

class Bar
{
public:
    Bar()
    {
    };
   
    const int var = 20;
};

class FUBAR
{
public:
    FUBAR()
    {
    };

    const int var = 30;
};

std::vector<std::variant<Foo*,Bar*,FUBAR*>> list;// Can I use template for this kind of stuff?
inline constexpr int itemCount = 3;

int main()
{
    std::cout << "Started";

    Foo* m_f = new Foo();
    Bar* m_b = new Bar();
    FUBAR* m_fb = new FUBAR();

    list.emplace_back(m_f);
    list .emplace_back(m_b);
    list.emplace_back(m_fb);

    std::cout << _::string_format("\nFoo:%i\tBar:%i\tFUBAR:%i\n\n\n\n", m_f->var, m_b->var, m_fb->var);

    std::string s;
    std::cin >> s;

    if (s == "delete")
        for (const auto& p : list)
        {
            const auto index = &p - &list[0];
            const auto curElement = list[index];

            // How to delete them?
            //delete std::get<0>(curElement);
            //delete std::get<1>(curElement);
            //delete std::get<2>(curElement);

        }
    else
        std::cout << "\n free memory!";

    return 0;
}

ADDITIONALLY: I exactly need to delete them by accessing them via vector with a method like std::get or something else:

for (const auto& p : list)
{
    const auto index = &p - &list[0];
    const auto curElement = list[index];

    // How to delete them?
    //delete std::get<0>(curElement);
    //delete std::get<1>(curElement);
    //delete std::get<2>(curElement);

}

Not like deleting local pointer objects right after displaying their value this way:

Foo* m_f = new Foo();
list.emplace_back(m_f);    
std::cout << m_f->var;
delete m_f;


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source