3

This may be a complicated question but I assume it has a simple answer.

So I have a struct that contains custom object types:

// header1.h

struct MyStruct
{
    MyClass myObject1;
    MyClass myObject2;
};

And I have a global pointer to a MyStruct. I am going to allocate and instantiate the struct using the new keyword. When I do so, I want to construct each myObject by name in an initializer list, as shown below.

// codeFile1.cpp

MyStruct *myStructPtr;

int main()
{
    myStructPtr = new MyStruct
    {                                     //syntax error: missing ';'
        .myObject1 = MyClass(arg1, arg2),
        .myObject2 = MyClass(arg1, arg2)
    };
}

The code snippet above has syntax errors, but it demonstrates what I want to do. Note that MyClass does not have a default constructor, so it must be given an argument list.

Thanks!

EDIT - CONCLUSION

As pointed out, my initialization list is C-style, which fails to work. Unfortunately the C++11 initializer-list does not meet my compiler requirements, and the option of throwing all arguments into a constructor is not practical.

So I took an alternative solution and changed the pointer structure to the following:

// header1.h

struct MyStruct
{
    MyClass *myObjectPtr1;
    MyClass *myObjectPtr2;
};

// codeFile1.cpp

MyStruct myStruct;

int main()
{
    myStructPtr.myObjectPtr1 = new MyClass(arg1, arg2);
    myStructPtr.myObjectPtr2 = new MyClass(arg1, arg2);
}

Thanks all!

Aaron Campbell
  • 562
  • 8
  • 19

3 Answers3

3

If MyStruct is an aggregate, you could use aggregate initialization to avoid defining a constructor:

myStructPtr = new MyStruct {{arg1, arg2}, {arg1, arg2}};

If not, please provide a constructor taking the appropriate arguments and call

myStructPtr = new MyStruct{arg1, arg2};
Pradhan
  • 16,391
  • 3
  • 44
  • 59
  • Using the aggregate initialization doesn't get rid of the "missing ';'" syntax error. Also seing a "MyStruct: no appropriate default constructor available" on the same line. – Aaron Campbell Feb 14 '15 at 00:18
  • This is _not_ aggregate initialization, guys. – Lightness Races in Orbit Feb 14 '15 at 00:25
  • @LightnessRacesinOrbit I am not sure what I am missing. From N3797, `8.5.4 [dcl.init.list]`, the first point says that the above initializer expression for the `new` is *list initialization*. The third point in the same section says `If T is an aggregate, aggregate initialization is performed`. And my answer opens with the assumption that `MyStruct` is an aggregate. – Pradhan Feb 14 '15 at 01:09
  • `[C++11: 8.5.1/1]:` "An _aggregate_ is an array or a class (Clause 9) with no user-provided constructors (12.1), no _brace-or-equal-initializers_ for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3)." – Lightness Races in Orbit Feb 14 '15 at 01:13
  • Fair enough, though: _if_ `MyStruct` were an aggregate then it would be aggregate initialisation (TIL) so, although misleading, your answer is not strictly wrong the way it is worded. Just testing! ;) – Lightness Races in Orbit Feb 14 '15 at 01:14
  • @LightnessRacesinOrbit I am offended! My answer has an if clause and an else clause :) – Pradhan Feb 14 '15 at 01:32
2

You're trying to use C's designated initializers, which are not part of C++. If you have a C++11 compiler, you can simply do the following:

MyStruct *myStructPtr = new MyStruct
{
    MyClass(arg1, arg2),
    MyClass(arg1, arg2)
};

Live demo

Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Wow! I didn't know you could do this in general. Which list initialization clause covers this? when `MyStruct` isn't an aggregate? Running through the conditions [here](http://en.cppreference.com/w/cpp/language/list_initialization), I am unable to understand why this is allowed. – Pradhan Feb 14 '15 at 00:08
  • What makes this possible in C++11 but not earlier? – Aaron Campbell Feb 14 '15 at 00:09
  • @Pradhan It's the same as your answer, in fact, I like your answer better because you avoided mentioning `MyClass` – Praetorian Feb 14 '15 at 00:11
  • 2
    @aaronncfca It requires list initialization which is part of C++11 – Praetorian Feb 14 '15 at 00:11
1

You will, somehow, need to chain your constructions together. Assuming you actually want the same arguments:

struct MyStruct
{
    MyStruct(int arg1, int arg2) : myObject(arg1, arg2), myObejct2(arg1, arg2) {}
    MyClass myObject1;
    MyClass myObject2;
};

MyStruct *s = new MyStruct(34, 42);

Or something like this:

struct MyStruct
{
    MyStruct(const MyClass& a1, const MyClass& a2) : myObject(a1), myObejct2(a2) {}
 .... 
};

MyStruct *s = new MyStruct(MyClass(1,2), MyClass(3,4));

or in C++11 initializer lists:

MyStruct *s = new MyStruct({1,2}, {3,4});

Many other similar solutions are available.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227