c++arraystemplatesconstructor

Initialization of class array in a template class


I have a class which uses a fixed number of member classes (mInpA, mInpA in my case)

class csAndGate : public csLogicCell
{
public:
    csAndGate() :
        mInpA(this),
        mInpB(this) 
    {}

    csLogicInp* InpA() { return &mInpA; }
    csLogicInp* InpB() { return &mInpB; }
    csLogicOut& OutY() { return mOutY; }
private:
    virtual void AnyInputChanged() override {
        int inA = mInpA.InpValue;
        int inB = mInpB.InpValue;
        int out = inA & inB;
        mOutY.setOutEvent(5, out);
    }

    csLogicInp mInpA;
    csLogicInp mInpB;
    csLogicOut mOutY;
};

Now I would like to change the class to a template class with the number input as a template parameter like so:

template<const int NumInp>
class csAndGate : public csLogicCell
{
public:
    csAndGate() :
        // how to initialize mInp[NumInp] array here ?
    {}

    csLogicInp* Inp(int No) { return &mInp[No]; }
    csLogicOut& OutY() { return mOutY; }
private:
    virtual void AnyInputChanged() override {
        int out = mInp[0].InpValue;
        for (int i = 1; i < NumInp; ++i) {
            out &= mInp[i].InpValue;
        }
        mOutY.setOutEvent(5, out);
    }

    csLogicInp mInp[NumInp] ;
    csLogicOut mOutY;
};

But I have nor idea how to make the initialization of the class array.
If there is now solution I must add a default constructor and a setParent() member function to my csLogicInp class to set the parent class.
But I would not be happy with this solution, because the initialization of the parent class is mandatory and this could be forgotten with a default constructor.


Solution

  • If you must use an array size known at compile time, then the std::array approach in the other answer is excellent.

    If std::vector is suitable for your program, then you could declare mInp as a vector, remove the template parameter to csAndGate then set the number of input gates as a constructor argument like the following.

    class csAndGate : public csLogicCell
    {
    public:
        explicit csAndGate(int NumInp):
            mInp(NumInp, this)
            {}
    
        csLogicInp* Inp(int No) { return &mInp[No]; }
        csLogicOut& OutY() { return mOutY; }
    private:
        virtual void AnyInputChanged() override {
            int out = mInp[0].InpValue; 
            for (auto &inp : mInp) {
                out &= inp.InpValue;
            }
            mOutY.setOutEvent(5, out);
        }
        
        std::vector<csLogicInp> mInp;
        csLogicOut mOutY;
    };