0

For some reason when I set some default values for the nested structure with a constructor, I get the following error. But it seems the code should work. Can someone tell me where am I going wrong?

#include <stdio.h>
#include <string.h>
#include <iostream>

using namespace std;

struct smallDude
{
    int int1;
    int int2;

    // Default constructor
    smallDude()
    {
        int1 = 70;
        int2 = 60;
    }
};

struct bigDude 
{
    // structure within structure
    struct smallDude second;
}first;

int main() 
{
    bigDude first = {{2, 3}};
    cout<< first.second.int1<<endl;
    cout<< first.second.int2;
    return 0;
}

Error Output:

main.cpp:28:28: error: could not convert ‘{2, 3}’ from ‘’ to ‘smallDude’
   28 |     bigDude first = {{2, 3}};
      |                            ^
      |                            |
      |                            
  • 2
    In your declaration of `bigDude`, the `struct smallDude second;` member should be declared as just `smallDude second;` In any case, the error message shown does not match the code shown. – Remy Lebeau Nov 19 '21 at 23:50
  • @RemyLebeau I edited the code, now, it should spit out the exact error (I must have copy pasted hastily in my trials). There was `bigDude first` instead of just `first` in the int main(). – Abdulla Masud Nov 20 '21 at 09:19
  • 1
    nope, the error still doesn't match the code. You can't initialize 2 data fields using 3 initializers. The code is using `{{2, 3}}` but the error message shows `{1, {3, 6}}` – Remy Lebeau Nov 20 '21 at 09:24
  • @RemyLebeau my bad!!! Changed the error output now. `{1, {3, 6}}` was from a previous code that I was running. So sorry about this silly mistake twice. – Abdulla Masud Nov 20 '21 at 09:32

2 Answers2

2

smallDude has a user-declared default constructor, so it is not an aggregate type, and thus cannot be initialized from a <brace-init-list> like you are attempting to do.

There are two way you can fix that:

  1. change the smallDude constructor to accept int inputs, like @rturrado's answer shows:
struct smallDude
{
    int int1;
    int int2;

    // constructor
    smallDude(int x, int y) : int1{x}, int2{y} {}
};

Online Demo

  1. get rid of all smallDude constructors completely (thus making smallDude an aggregate) and just assign default values to the members directly in their declarations, eg:
struct smallDude
{
    int int1 = 70;
    int int2 = 60;
};

Online Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • The first method works but the second one isn't working on the online compiler that I am using. Is it a compiler issue? [demo](https://onlinegdb.com/1pW9dHh-z) – Abdulla Masud Nov 20 '21 at 09:42
  • 1
    @AbdullaMasud add the `-std=c++14` flag to that compiler, and then it works fine. – Remy Lebeau Nov 20 '21 at 09:52
  • Thank you! Though could you explain `: int1{x}, int2{y} {}` this part of the first method? or can you tell me what this is called so I can look it up? – Abdulla Masud Nov 20 '21 at 10:26
  • 2
    @AbdullaMasud That's called _member initializer list_. It's the preferred option, rather than to initialize the members within the body of the constructor: https://en.cppreference.com/w/cpp/language/constructor. – rturrado Nov 20 '21 at 11:44
  • 1
    @AbdullaMasud [C++, What does the colon after a constructor mean?](https://stackoverflow.com/questions/2785612/) – Remy Lebeau Nov 20 '21 at 20:53
1

You are missing a smallDude constructor receiving two int values:

smallDude(int x, int y) : int1{x}, int2{y} {}

Demo

rturrado
  • 7,699
  • 6
  • 42
  • 62