c++classvectorpolymorphism

Receiving error: "error: static assertion failed: result type must be constructible from value type of input range" when constructing class vectors


I am trying to create a script that uses polymorphism to create a set of linking vectors within parent/child class structure. So far I have got the classes setup, but when trying to test the code I receive an error involving static assertion. When analysing the code line by line, I run into the error when I call 'vector.begin() & vector.end()'.

Here is the full script:

#include <iostream>
#include <vector>
using namespace std;

class A
{
public:
    vector<vector<A *>> Container;
};

class B : A
{
};

class C : A
{
};

class D : A
{
};

int main()
{
    A ABaseClass;

    B b1, b2;
    C c1, c2;
    D d1, d2;

    vector<B *> b_classes = {&b1, &b2};
    vector<C *> c_classes = {&c1, &c2};
    vector<D *> d_classes = {&d1, &d2};

    ABaseClass.Container = {
        {b_classes.begin(), b_classes.end()},
        {c_classes.begin(), c_classes.end()},
        {d_classes.begin(), d_classes.end()}};
}

Compiling gives this error:

error: static assertion failed: result type must be constructible from value type of input range
  138 |       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
      |                                                                        ^~~~~

error: static assertion failed: result type must be constructible from value type of input range
note: 'std::integral_constant<bool, false>::value' evaluates to false

I have narrowed down the cause of the error to this section:

ABaseClass.Container = {
        {b_classes.begin(), b_classes.end()},
        {c_classes.begin(), c_classes.end()},
        {d_classes.begin(), d_classes.end()}};

Following the root of the problem leads me to the file 'stl_uninitialized.h', and the line:

[138]      static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
                                                                            ^~~~~

I have been trying to get the child classes to be tracked by the parents but I am unfamiliar with vectors and pointers so I am a bit stuck. Any help with moving forward would be greatly appreciated.


Solution

  • Upcast to a base class is ill-formed if the inheritance is not public. i.e

    struct base {};
    class derived : base {}; // private inheritance
    
    int main(){
        derived a;
        auto & b = static_cast<base &>(a); // invalid
    }
    

    That's exactly what that last assignment expression is trying to do. You will need to inherit publically. i.e

    class A
    
    public:
    vector<vector<A *>> Container;
    };
    
    class B : public A
    {
    };
    
    class C : public A
    {
    };
    
    class D : public A
    {
    };
    

    EDIT: This is the answer originally cited:

    class A
    
    public:
    vector<vector<A *>> Container;
    };
    
    struct B : A
    {
    };
    
    struct C : A
    {
    };
    
    struct D : A
    {
    };