Cpp Notes

variadic_class_with_variadic_members

#include <iostream>
#include <tuple>
#include <utility>

// Variadic class template with index sequence
template <typename... Args>
class VariadicClass {
private:
    // note: Because the trailing return type is part of the function declaration
    // rather than the definition, it can't look ahead to see what else is declared
    // in the class, so you need to declare that member above the function declaration.
    std::tuple<Args...> members_;
public:
    // Constructor that forwards arguments to the tuple
    VariadicClass(Args... args) : members_(std::make_tuple(args...)) {}

    // Access member by index using std::get
    template <std::size_t N>
    auto get() -> decltype(std::get<N>(members_)) {
        return std::get<N>(members_);
    }

    // Print all members using index sequence
    void printMembers() const {
        printTuple(members_, std::index_sequence_for<Args...>{});
    }

private:
    // Helper function to print tuple elements using index sequence
    template <typename Tuple, std::size_t... Is>
    void printTuple(const Tuple& tuple, std::index_sequence<Is...>) const {
        // Fold expression to iterate and print each element
        ((std::cout << std::get<Is>(tuple) << " "), ...);
        std::cout << std::endl;
    }
};

int main() {
    // Create an instance of VariadicClass with multiple elements of the same type
    VariadicClass<int, double, std::string, int, double> myClass(42, 3.14, "Hello", 7, 2.71);

    // Access and print individual members by index
    std::cout << "First int: " << myClass.get<0>() << std::endl;
    std::cout << "First double: " << myClass.get<1>() << std::endl;
    std::cout << "String: " << myClass.get<2>() << std::endl;
    std::cout << "Second int: " << myClass.get<3>() << std::endl;
    std::cout << "Second double: " << myClass.get<4>() << std::endl;

    // Print all members
    myClass.printMembers();

    return 0;
}