Steve
Steve

Reputation: 859

How to initialize an array of structs containing union in C++?

I have been struggling with initialization of an array containing struct members with union.
Let's say I have following declarations in C++

enum class FilterType { kLowPass, kAverage };
    
enum class FilterLowPassConfig {
    k1kHzLowPass = 0,
    k10kHzLowPass = 1,
    k20kHzLowPass = 2,
    k40kHzLowPass = 3
};
    
enum class FilterAverageConfig {
    kWindowSize256 = 0,
    kWindowSize128 = 1,
    kWindowSize64 = 2,
    kWindowSize32 = 3
};
    
union FilterConfig {
    FilterLowPassConfig low_pass_config;
    FilterAverageConfig average_config;
};
    
struct FilterSelect
{
    FilterType filter_type;
    FilterConfig filter_config;
};

Now I define an array:

FilterSelect filter_select[2];

Is it possible to initialize the array filter_select with brace-enclosed initializer list?

Upvotes: 1

Views: 85

Answers (1)

wohlstad
wohlstad

Reputation: 29009

You can use std::variant instead of a C style union.

In modern C++ std::variant is recommended in general (see more info here), and with it you can do:

#include <variant>

enum class FilterType { kLowPass, kAverage };

enum class FilterLowPassConfig {
    k1kHzLowPass = 0,
    k10kHzLowPass = 1,
    k20kHzLowPass = 2,
    k40kHzLowPass = 3
};

enum class FilterAverageConfig {
    kWindowSize256 = 0,
    kWindowSize128 = 1,
    kWindowSize64 = 2,
    kWindowSize32 = 3
};

using FilterConfig = std::variant<FilterLowPassConfig, FilterAverageConfig>;

struct FilterSelect
{
    FilterType filter_type;
    FilterConfig filter_config;
};

int main() 
{
    [[maybe_unused]] FilterSelect filter_select[2] = 
    { { FilterType::kLowPass,  FilterLowPassConfig{FilterLowPassConfig::k1kHzLowPass}},
      { FilterType::kAverage,  FilterAverageConfig{FilterAverageConfig::kWindowSize256}} };
}

Live demo

An additional recommendation is to use std::array insread of a C style array:

#include <array>

// ...

int main() 
{
    [[maybe_unused]] std::array<FilterSelect, 2> filter_select =
    { FilterSelect{FilterType::kLowPass, FilterLowPassConfig{FilterLowPassConfig::k10kHzLowPass}},
      FilterSelect{FilterType::kLowPass, FilterLowPassConfig{FilterLowPassConfig::k10kHzLowPass}} };
}

Live demo with std::array

Upvotes: 2

Related Questions