Heterogeneous Initializer Lists

Can std::initializer_list be used with heterogeneous data types in any way?

std::initializer_list in C++ is designed to handle homogeneous data types, meaning all elements must be of the same type.

However, there are scenarios where you might want to work with heterogeneous data. Although std::initializer_list itself cannot handle heterogeneous types, there are alternative approaches to achieve similar functionality.

One common approach is to use std::tuple, which can store elements of different types:

#include <iostream>
#include <tuple>

int main() {
  std::tuple<int, double, std::string> myTuple{
    1, 2.5, "Hello"}; 
  std::cout << std::get<0>(myTuple) << ", "
            << std::get<1>(myTuple) << ", "
            << std::get<2>(myTuple);
}
1, 2.5, Hello

In this example, std::tuple allows storing an int, double, and std::string together. You can access each element using std::get<>().

If you need a container that can dynamically handle different types, consider using std::variant or a base class with pointers to derived classes:

#include <iostream>
#include <variant>
#include <vector>

int main() {
  std::vector<std::variant<
    int, double, std::string>
  > vec{1, 2.5, "Hello"}; 

  for (const auto& elem : vec) {
    std::visit([](auto&& arg) {
      std::cout << arg << ", ";
    }, elem);
  }
}
1, 2.5, Hello

std::variant can hold any one of the specified types at a time. Using std::visit, you can apply a visitor function to handle each type.

For more complex scenarios, you might use a base class with a polymorphic approach:

#include <iostream>
#include <vector>
#include <memory>

class Base {
public:
  virtual void Log() const = 0;
  virtual ~Base() = default;
};

class DerivedInt : public Base {
  int value;
public:
  DerivedInt(int val)
    : value{val} {}
  void Log() const override {
    std::cout << value << ' ';
  }
};

class DerivedDouble : public Base {
  double value;
public:
  DerivedDouble(double val)
    : value{val} {}
  void Log() const override {
    std::cout << value << ' ';
  }
};

class DerivedString : public Base {
  std::string value;
public:
  DerivedString(std::string val)
    : value{val} {}
  void Log() const override {
    std::cout << value << ' ';
  }
};

int main() {
  std::vector<std::unique_ptr<Base>> vec;
  vec.push_back(
    std::make_unique<DerivedInt>(1)
  );
  vec.push_back(
    std::make_unique<DerivedDouble>(2.5)
  );
  vec.push_back(
    std::make_unique<DerivedString>("Hello")
  );

  for (const auto& elem : vec) {
    elem->Log();
  }
}
1 2.5 Hello

This polymorphic approach allows you to store different types in a container, each derived from a common base class. This technique is flexible but requires more boilerplate code.

While std::initializer_list is limited to homogeneous types, using std::tuple, std::variant, or polymorphism provides powerful alternatives to handle heterogeneous data effectively.

List, Aggregate, and Designated Initialization

A quick guide to creating objects using lists, including std::initializer_list, aggregate and designated initialization

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

List Initialization with Private Members
Can we use list initialization for classes with private or protected members?
Aggregate Initialization for Nested Structures
How does aggregate initialization work for complex types with nested structures?
Using Initializer Lists in Custom Containers
How can we use std::initializer_list to initialize custom container types?
Designated Initializers with Private Members
Can designated initializers be used with types that have private or protected members?
Aggregate Initialization with Inheritance
How does aggregate initialization interact with inheritance and derived classes?
List Initialization with constexpr and constinit
How does list initialization interact with constexpr and constinit specifiers in C++20?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant