0

I am trying to make an array of structs, but I am getting the error no matching function for call to 'Cell::Cell()'.

Cell is the name of my struct. Here is some of my code:

struct Cell{
    int number;

    Cell(int n){
        number = n;
    }
};

class MyClass{
    public:
        int nCells;

        void inject(){
            std::cout << "Enter number:";
            string in;
            std::cin >> in;
            int amount = in.size()/3;

            Cell cells [amount]; // <-- error

            int index = 0;
            int t = in.size();
            while (t >= 3){
                cells[index] = new Cell(atoi(in.substr(t-3,3).c_str());
                t -= 3;
                index++;
            }
        }

        MyClass(int n){
            nCells = n;
        }
};

Cell cells [amount]; is giving me the error. I am new to classes, but I know how to make arrays of primitive types. int cells [amount]; would work, for instance.

But how am I supposed to make an array of type Cell ?

1
  • 1
    Where's default constructor in Cell? You does not have it. Commented Jan 29, 2014 at 16:04

3 Answers 3

4

Cell doesnt have a default constructor (as soon as you specify another constructor the compiler will not create a default constructor anymore). However the definition Cell cells[amount] will automatically default initialize every element.

I think the best way in this particular situation is simply to implement a default constructor:

struct Cell{
    int number;

    Cell() : number(0)
    {
    }

    Cell(int n) : number(n)
    {
    }
};

Also notice as amount is not known at compile time, Cell cells[amount] is basically illegal. However some compilers have extensions to allow this. But its better if you heap allocate it:

Cell* cells = new Cell[amount];

Dont forget to destroy it however.

Sign up to request clarification or add additional context in comments.

11 Comments

Modern C++ prefers std::shared_ptr<Cell> cells(new Cell[amount]), because then you can't forget to destroy it.
It works! I have a side question: Is there a difference between the way we wrote our constructors? You write Name(argument): number(n) {} , while I wrote Name(argument) { number(n) }
It's the same story as your question. " : number(n)" calls the constructor for number with parameter n. { number = n; } calls the default constructor for number, and then AFTER does number= n. In this case, no real difference, but in general it's less efficient - and if you don't have a default constructor (like you didn't) it would actually fail your way.
No, no, no with regards to new Cell[amount]. Use std::vector<Cell> cells(amount);. (There's practically never a case where you'd use an array new.)
@Paranaix His code didn't work. Array new is almost always a bad solution, when we have std::vector.
|
2

If you know how long the array is, you can use c++11 initialization. This will do :

int main()
{
    Cell c[3]{ Cell(1), Cell(2), Cell(3) };
}

By the way this

Cell cells [amount];

is using VLAs, and that is not supported by c++ (only as extension for some compilers).

In c++, much better would be to use std::vector :

#include <vector>


struct Cell{
    int number;

    Cell(int n){
        number = n;
    }
};

int main()
{
    int n = 5;

    std::vector< Cell > c;

    for ( int i =0; i < n; ++ i )
    {
        c.emplace_back( Cell( i ) );
    }
}

2 Comments

Why emplace_back here, which is only supported by C++11, when push_back will generate exactly the same code.?
@JamesKanze No idea. As you said, push_back works fine as well :)
0

By doing Cell cells [amount]; you are calling the Cell constructor, but in this case you don't have a default constructor for Cell, so you must use pointers instead, you are using them in the while stuff.

Just change

Cell cells [amount];

for

Cell* cells [amount];

4 Comments

@JohnDibling, it does have a constructor, but not a default one...thats why it is crashing.
@JohnDibling It has a constructor, but not a default constructor.
Oh, it sure didn't look like it had any defined constructors at all when I viewed this question earlier. I must have just missed it.
This is about the worst solution imaginable. What's wrong with providing a default constructor, or using std::vector<Cell>? The less you allocate dynamically, the better you'll be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.