Home > Software engineering >  Constructor with multiple parameters throws 'expression list treated as compound expression in
Constructor with multiple parameters throws 'expression list treated as compound expression in

Time:11-03

I created the following test program to demonstrate an error I can't seem to resolve. I have searched and read several articles, but none that I've found explain how to resolve this particular problem.

I created a class with multiple constructors, one of which has multiple parameters. I can declare instances of the class testing each constructor, but when I declare an array of classes I can only use the default constructor or the version with a single parameter.

I get a compile error: "expression list treated as compound expression in initializer [-fpermissive]" when I create an array of classes and attempt to use the multiparameter constructor. I am using C 11 mingw compiler, see kc5 in the below sample program.

Can anyone explain the meaning of the error and how to properly declare an array of class objects when the constructor has multiple parameters?

#include <iostream>
using namespace std;

class KClass {
public:
int x=0;

KClass(){};//default constructor w/o parameters works

KClass(int a){//single parameter constructor works
x = a;
return;
}

KClass(char c,int a){//multi parameter constructor
x = a;
//not using char c for now
return;
}

~KClass(){};//destructor

int getx(){return x;}
void setx(int data){x=data;return;}
};

//class is declared, let's create some instances of the class
KClass kc0;//works
KClass kc1(5);//works
KClass kc2('k',7);//works
KClass kc3[2];//works
KClass kc4[2](4);//works
//next line does not compile (how do I fix?)
KClass kc5[2]('r',4);//compile error: expression list treated as compound expression in initializer

int main()
{
//do something

  getchar();
  return 0;
}

I learned that using the 'new' keyword works, however, the solution doesn't seem elegant to me and I don't understand why 'new' is required.

KClass *kc6 = new KClass[2]; //works

and then in main() I initialize using the multiparameter constructor.

kc6[0] = KClass('a',2);
kc6[1] = KClass('b',3);

CodePudding user response:

Such an initialization of an array

KClass kc5[2]('r',4);

is allowed by the C 20 Standard. In this case the constructor with one parameter will be called for each element.

If the compiler does not support the C 20 Standard then it will issue an error.

Otherwise in C 20 you could else write

KClass kc5[2]( { 'r',4 } );

and for the first element the constructor with two parameters will be called.

CodePudding user response:

Thanks to Vlad for his answer. I wanted to add that I learned how to make this work with the C 11 standard (sample program below).

It appears my problem resulted from ignorance of the correct syntax to use when a multiparameter constructor is used with an array. The sample program shows what works and an unexpected result.

Because I created 3 class objects on the heap I was careful to delete those objects before the program terminates to avoid a memory leak (note to beginning coders).

#include <iostream>
using namespace std;

class KClass {
public:
int x=0;

KClass(){
cout << "default constructor called" << endl;
};//default constructor w/o parameters works

KClass(int a){//single parameter constructor works
x = a;
cout << "single parameter constructor a: " << a << endl;
return;
}

KClass(char c,int a){//multi parameter constructor
    cout << "visiting multi param constructor c: " << c << " a: " << a << endl;
x = a;
//not using char c for now
return;
}

~KClass(){
cout << "default destructor" << endl;
};//destructor

int getx(){return x;}
void setx(int data){x=data;return;}
};

//class is declared, let's create some instances of the class
KClass kc0;//works default constructor
KClass kc1(5);//works single parameter constructor
KClass kc2('k',7);//works multi parameter constructor
KClass kc3[2];//works default constructor called twice
KClass kc4[2](4);//works single parameter constructor called twice

//next line does not compile (how do I fix?)
//no compile: KClass kc5[2]('r',4);//compile error: expression list treated as compound expression in initializer

KClass *kc6 = new KClass[2];//defaullt constructor called twice

//notice the syntax needed to call the multiparameter constructor twice
KClass *kc7 = new KClass[2]{{'c',8},{'g',9}};//works  multi parameter constructor called twice

//next line calls the single parameter constructor twice; the char 'd' is treated as int 100 (its ascii int value)
KClass *kc8 = new KClass[2]{'d',6};//works but not as expected single parameter constructor called twice

int main()
{
//do something
kc6[0] = KClass('a',2);
kc6[1] = KClass('b',3);
//use kc7 to prove it worked
cout << "kc7[0].getx(): " << kc7[0].getx() << endl;
cout << "kc7[1].getx(): " << kc7[1].getx() << endl;
cout << endl;
cout << "kc8[0].getx(): " << kc8[0].getx() << endl;
cout << "kc8[1].getx(): " << kc8[1].getx() << endl;
cout << endl;

//because we used the new keyword for kc6, kc7 and kc8:
//those objects are on the heap (vs the stack) so we must manually delete to avoid memory leak
delete []kc6;
kc6=nullptr;
delete []kc7;
kc7=nullptr;
delete []kc8;
kc8=nullptr;

  getchar();
  return 0;
}
  • Related