Search code examples
c++aggregatec++14list-initialization

Initialize a private aggregate from a braced-init-list


If I try to compile

class triangle
{
private:
    std::array<std::array<double, 2>, 3> m_vertices;
};

triangle const unit_triangle{ { { { 0, 0 }, { 1, 0 }, { 0, 1 } } } };

I get the error message

cannot convert from 'initializer list' to 'triangle'.

If I replace private by public, the code compiles successfully. Since I don't want to do that: What do I need to do, if I want to initialize unit_triangle from a braced-init-list?


Solution

  • Having a private member prevents triangle from being an aggregate. It's being an aggregate that allows you to list-initialize a triangle without triangle having a constructor. That's why it works when you replace private with public.

    To support the syntax you want, you simply need to add the appropriate constructor. In this case:

    class triangle
    {
    public:
        triangle(std::array<std::array<double, 2>, 3> const& v)
            : m_vertices(v)
        { }
    
    private:
        std::array<std::array<double, 2>, 3> m_vertices;
    };