Search code examples
c++inheritanceaggregate-initialization

How to avoid {} when using aggregate initialization with empty base class


C++17's aggregate initialization for base class is awesome, but it is verbose when the base is only there to provide some functions (so no data members).

Here is minimal example:

#include <cstddef>
struct base_pod
{
    // functions like friend compare operator
};
template<typename T, std::size_t N>
struct der_pod : public base_pod
{
    T k[N];
};

int main()
{
    der_pod<int, 2> dp {{}, {3, 3} };
}

As the example above shows, I have to provide empty {}, otherwise compile error will occur. live demo. If I omit it:

prog.cc:15:28: error: initializer for aggregate with no elements requires explicit braces
        der_pod<int, 2> dp{3, 3};
                           ^
prog.cc:15:31: warning: suggest braces around initialization of subobject [-Wmissing-braces]
        der_pod<int, 2> dp{3, 3};
                              ^
                              {}
1 warning and 1 error generated.

Any workaround or pre-C++17 way?


Solution

  • You can still provide constructor, for example:

    template <typename T, std::size_t N> using always_t = T;
    
    struct base_pod
    {
        // functions like friend compare operator
    };
    template<typename T, typename Seq> struct der_pod_impl;
    
    template<typename T, std::size_t ... Is>
    struct der_pod_impl<T, std::index_sequence<Is...>> : base_pod
    {
        der_pod_impl(always_t<T, Is>... args) : k{args...} {}
    
        T k[sizeof...(Is)];
    };
    
    template<typename T, std::size_t N>
    using der_pod = der_pod_impl<T, std::make_index_sequence<N>>;
    

    Demo