Brett Ryland Brett Ryland - 1 year ago 46
C++ Question

Modifying a member initializer list

I have some code which effectively reduces to

#include <vector>
class A {
std::vector<int> m_sizes;
public:
A(std::initializer_list<int> const& sizes) : m_sizes(sizes) {}
};

class B {
A m_a;
public:
B(int size_front, int size_back, std::initializer_list<int> const& sizes) : m_a({ size_front, sizes, size_back }) {}
};


The compiler complains that no instance of
A::A
matches the argument list.
Is there some way to flatten out the
{ int, std::initializer_list<int>, int }
to a
std::initializer_list<int>
or do I have to give
A
an extra constructor to handle this situation? What if I couldn't modify the
A
class?

Answer Source

What you are trying to do is not possible: initializer_list<T> must be constructed from a list of items of type T, whose count is known at compile time. Inserting an existing list in the middle does not work.

You can work around this problem by adding a constructor overload that takes a vector<int> directly, and forwarding calls to it:

class A {
    std::vector<int> m_sizes;
public:
    A(const std::vector<int>& sizes) : m_sizes(sizes) {}
    A(std::initializer_list<int> const& sizes) : A(std::vector(sizes)) {}
};
class B {
    A m_a;
    std::vector<int> frame(int size_front, int size_back, std::initializer_list<int> const& sizes) {
        std::vector res;
        res.push_back(size_front);
        std::copy(sizes.begin(), sizes.end(), std::back_inserter(res));
        res.push_back(size_back);
        return res;
    }
public:
    B(int size_front, int size_back, std::initializer_list<int> const& sizes) : m_a(frame(size_front, size_back, sizes)) {}
};
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download