admin管理员组

文章数量:1201202

I have a class that requires an a list of elements to initialize. I have a sub-class that whenever used, should always add elements to the initializer_list passed through,

#include <vector>
#include <iostream>

class A
{
public:
    A(std::initializer_list<int> things)
    :
        m_things(things)
    {}

    virtual ~A() {}

    virtual void X() const noexcept
    {
        for(const auto& i : m_things)
        {
            std::cout << i << std::endl;
        }
    }

protected:
    std::vector<int> m_things;
};

class B : public A
{
public:
    B(std::initializer_list<int> things)
    :
        A(things /* how do I add some elements here? */)
    {}
};

int main()
{
    A* a = new B({1,2,4});
    a->X();
    return 0;
}

In addition, I might need to manipulate the passed values, in either A or B before putting them into either the m_things or As constructor, how would I do that?

The current answer provides a way to accomplish this using std::views::concat, however, I don't currently have access to GCC 15 (only currently supporting compiler for this C++26 feature). I'm currently using GCC 14.2.1

I have a class that requires an a list of elements to initialize. I have a sub-class that whenever used, should always add elements to the initializer_list passed through,

#include <vector>
#include <iostream>

class A
{
public:
    A(std::initializer_list<int> things)
    :
        m_things(things)
    {}

    virtual ~A() {}

    virtual void X() const noexcept
    {
        for(const auto& i : m_things)
        {
            std::cout << i << std::endl;
        }
    }

protected:
    std::vector<int> m_things;
};

class B : public A
{
public:
    B(std::initializer_list<int> things)
    :
        A(things /* how do I add some elements here? */)
    {}
};

int main()
{
    A* a = new B({1,2,4});
    a->X();
    return 0;
}

In addition, I might need to manipulate the passed values, in either A or B before putting them into either the m_things or As constructor, how would I do that?

The current answer provides a way to accomplish this using std::views::concat, however, I don't currently have access to GCC 15 (only currently supporting compiler for this C++26 feature). I'm currently using GCC 14.2.1

Share Improve this question edited Jan 23 at 2:16 NeomerArcana asked Jan 22 at 12:39 NeomerArcanaNeomerArcana 2,2494 gold badges27 silver badges57 bronze badges 15
  • You could add those additional things as a second parameter to A, and A have another constructor with two initializer_list parameters. – Eljay Commented Jan 22 at 12:47
  • @Eljay but I'd still end up with two initializer_lists that I'd need to concat together in the vector's constructor. – NeomerArcana Commented Jan 22 at 12:55
  • A(std::initializer_list<int> things, std::initializer_list<int> more_things) : m_things(things) { m_things.insert(m_things.end(), more_things); } – Eljay Commented Jan 22 at 12:58
  • That's not initializing the vector though. I need it to concat them during initialization. – NeomerArcana Commented Jan 22 at 13:01
  • 3 initializer_list is immutable and contiguous, you can only create non empty ones with explicit {..} syntax... – Jarod42 Commented Jan 22 at 13:05
 |  Show 10 more comments

1 Answer 1

Reset to default 4

You can't do it with std::initialiser_list, as that can't be modified, but you can use a different constructor.

template< class R, class T >
concept container_compatible_range =
    std::ranges::input_range<R> &&
    std::convertible_to<std::ranges::range_reference_t<R>, T>;

class A
{
public:
    A(std::initializer_list<int> things)
    :
        m_things(things)
    {}
    A(std::from_range_t from_range, container_compatible_range<int> auto things)
    :
        m_things(from_range, things)
    {}

    virtual ~A() {}

    virtual void X() const noexcept
    {
        for(const auto& i : m_things)
        {
            std::cout << i << std::endl;
        }
    }

protected:
    std::vector<int> m_things;
};
    
class B : public A
{
    static constexpr std::initializer_list<int> stuff = { 10, 11, 12 };
public:
    B(std::initializer_list<int> things)
    :
        A(std::from_range, std::views::concat(things, stuff))
    {}
};

int main()
{
    A* a = new B({1,2,4});
    a->X();
    return 0;
}

本文标签: