Home > Blockchain >  How to conditionally initialize a member of a struct?
How to conditionally initialize a member of a struct?

Time:12-04

I am beginning to learn C struct. After creating a struct named Person, I tried to declare a boolean variable named genderBoolean in the struct of Person, and a string variable named gender. I tried to use if-else statement for the following condition: if genderBoolean is true, then gender is male, but if genderBoolean is false, then gender is female. I tried to put the if-else statement outside of the struct, but the IDE says

Identifier "genderBoolean" is undefined

which causes another compilation error.

It seems that if-else statement cannot be used within struct in C . I found out that adding a # before the if statement and adding #endif can solve the compilation error of "expected a declaration" in Microsoft Visual Code 2022, but the output of the program is:

"Name = Mike Gender = Age = 50 Nationality = American"

I expected its output to be : "Name = Mike Gender = male Age = 50 Nationality = American"

My code also generates compilation message that says the variable genderBoolean is uninitialized, but it can run:

#include <iostream>

using namespace std;
int main() {
    struct Person {
        string name;
        bool genderBoolean;
        string gender;
        string age;
        string nationality;
        #if(genderBoolean == true) {
            gender = "male";
        }
        else if (genderBoolean == false) {
            gender = "female";
        }
        #endif
    };
    Person person1;
    person1.name = "Mike";
    person1.genderBoolean = true;
    person1.age = "50";
    person1.nationality = "American";

    cout << "Name = " << person1.name << " Gender = " << person1.gender <<
        " Age = " << person1.age << " Nationality = " << person1.nationality <<
        endl;
    return 0;
}

I tried to put the if-else statement outside of the struct but it says identifier "genderBoolean" is undefined.

I expected its output to be : "Name = Mike Gender = male Age = 50 Nationality = American"

What actually resulted : "Name = Mike Gender = Age = 50 Nationality = American"

CodePudding user response:

Here are a few different ways to handle it using a constructor and a setter. Keep in mind that adding a parameterized constructor means the struct does not have a default constructor so you'd need special care to put it in an array and such. Adding a default constructor is left to you. I would advise making the member variables private and providing methods to set them so you can add error checking and preserve invariants like keeping the two gender variables in sync.

I added #include <string> because you should always include what you use and not depend on another file to include it since that may not always be the case and removed using namespace std; because it's a bad habit. Read Why is "using namespace std;" considered bad practice? for more information.

#include <iostream>
#include <string>

enum class Gender
{
    Male,
    Female
};

struct Person 
{
    std::string name;
    bool genderBoolean;
    std::string gender;
    std::string age;
    std::string nationality;

    Person(const std::string& name, Gender genderType, 
        const std::string& age, const std::string& nationality)
    : name(name)
    , genderBoolean(genderType == Gender::Male)
    // A way to initialize the gender
    , gender(genderType == Gender::Male ? "male" : "female")
    , age(age)
    , nationality(nationality)
    {
        // A way to assign the gender
        // If you use this remove the one above
        // You don't need both
        //if (genderBoolean)
        //{
        //    gender = "male";
        //}
        //else
        //{
        //   gender = "female";
        //}
    }

    void setGender(Gender genderType)
    {
        // A way to change the gender
        // Would be best if the member variables were private
        // But would not prevent the class from making them mismatch
        // by modifying the gender variable directly
        if (genderType == Gender::Male)
        {
            gender = "male";
        }
        else
        {
           gender = "female";
        }
    }

    friend std::ostream& operator<<(std::ostream& out, const Person& p);
};

std::ostream& operator<<(std::ostream& out, const Person& p)
{
    out << "Name = " << p.name 
        << ", Gender = " << p.gender
        << ", Age = " << p.age
        << ", Nationality = " << p.nationality
        << "\n";

    return out;
}

int main() 
{
    Person person1("Mike", Gender::Male, "50", "American");
    std::cout << person1;
    person1.setGender(Gender::Female);
    std::cout << person1;

    return 0;
}

Demo

Output:

Name = Mike, Gender = male, Age = 50, Nationality = American
Name = Mike, Gender = female, Age = 50, Nationality = American
  • Related