1

I'm writing a periodic table program to help me understand classes. I want to be able to display/sort the elements by several properties such as whether it's a metal, nonmetal, or metalloid. I'm not sure hwo to do it, but my first guess was to create an array of objects; however, I'm having problems using my constructor to set the values.

Class

class Element{
    public:
       enum class groupNames {  HYDROGEN, ALKALI, ALKALINE, GROUP_THREE, GROUP_FOUR, GROUP_FIVE,
                                GROUP_SIX, GROUP_SEVEN, GROUP_EIGHT, GROUP_NINE, GROUP_TEN,
                                GROUP_ELEVEN,GROUP_TWELVE, GROUP_THIRTEEN, GROUP_FOURTEEN,
                                GROUP_FIFTEEN, CHALCOGEN, HALOGEN, NOBLE_GAS
                                };
        enum class orbitals {ORBITAL_NOTSET, S_BLOCK, P_BLOCK, D_BLOCK, F_BLOCK};
        enum class metal_status {METAL = 0, METALLOID, NONMETAL};
        Element();
        Element(int aNumber, int pNumber,groupNames groupnames, metal_status MetalStatus, orbitals Orbital,std::string eName, std::string eSybol);
        void displayProperties();

    private:
        groupNames groupNumber;
        orbitals orbital;
        metal_status metalStatus;
        std::string elementSymbol;
        std::string elementName;
        int atomicNumber;
        int periodNumber;
};

Element::Element()
{
    atomicNumber = 0;
    periodNumber = 0;
    groupNumber = groupNames::HYDROGEN;
    metalStatus = metal_status::METAL;
    orbital = orbitals::ORBITAL_NOTSET;
    elementName = "NULL";
    elementSymbol = "NULL";
}

Element::Element(int aNumber, int pNumber,groupNames groupnames, metal_status MetalStatus, orbitals Orbital,std::string eName, std::string eSymbol)
{
    groupNumber = groupnames;
    metalStatus = MetalStatus;
    orbital = Orbital;
    atomicNumber = aNumber;
    periodNumber = pNumber;
    elementName = eName;
    elementSymbol = eSymbol;
}

void Element::displayProperties()
{
    std::cout << elementName << ", " << elementSymbol << "\n"
              << "Group Number: " << as_integer(groupNumber) << "\n"
              << "Metal Status: " << as_integer(metalStatus) << "\n"
              << "Orbital: "      << as_integer(orbital) << "\n"
              << "Atomic Number: "<< atomicNumber << "\n"
              << "Period Number: "<< periodNumber;
}

Previous Method of Initialization //Works fine, the problem is I can't sort by properties

Element Hydrogen(1,1, Element::groupNames::HYDROGEN, Element::metal_status::NONMETAL, Element::orbitals::S_BLOCK, "Hydrogen", "H");
Element Helium(2, 1, Element::groupNames::NOBLE_GAS, Element::metal_status::NONMETAL, Element::orbitals::S_BLOCK, "Helium", "He");

std::array Method -- Problem!

std::array<Element, 115> Elements =
{
    Elements[0],
    Elements[1](1,1, Element::groupNames::HYDROGEN, Element::metal_status::NONMETAL, Element::orbitals::S_BLOCK, "Hydrogen", "H")
};

Error: error: no match for call to '(std::array::value_type {aka Element}) (int, int, Element::groupNames, Element::metal_status, Element::orbitals, const char [9], const char [2])'

3
  • 2
    You seem to be using elements of an uninitialized std::array in the initialization of said array. Commented Feb 4, 2014 at 4:46
  • Crysis - for others (and if I'm not mistaken) - can you correct the code to remove referencing the uninitialized array inside the initialization list? Also, minor point, but the enum is actually named groupNames in your code, but you refer to it as group - like I say, minor point, but it's nice to not have questions with erroneous code. Commented Feb 4, 2014 at 5:27
  • I can change the group. I have a typeset set up, and I didn't change that when it as added here. As far as the array, that was part of the problem; I don't see why I should correct the code in my question when it'll lead to confusion for those that may later come across this. I also may be misunderstanding you, I've had 4 hours of sleep these past two nights because of A.P. classes. Commented Feb 5, 2014 at 5:42

1 Answer 1

3

You may need two sets of braces (I was pulling my hair out figuring out what clang was complaining about.) I suggest uniform initialization. Also, I prefixed your enums with Element for qualification and changed them to match what their names are in your class definition.

std::array<Element, 115> Elements =
{{
    {},
    {1,1, Element::groupNames::HYDROGEN, Element::metal_status::NONMETAL, Element::orbitals::S_ORBITAL, "Hydrogen", "H"}
}};

Alternatively, you can try:

std::array<Element, 115> Elements
{  
  Element(), 
  Element(1,1, Element::groupNames::HYDROGEN, Element::metal_status::NONMETAL, Element::orbitals::S_ORBITAL, "Hydrogen", "H")  
};
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks. I'm about to try this out. I have a typedef set up; that's why my code says group:: and metalStat::.
@Crysis Also, you can replace as_integer with static_cast<int>, as an enum class's underlying type is int by default.
I'm new to uniform initialization - can you explain why the two sets of curly braces are necessary?
@remyabel I was trying to figure that out, but I forgot about staic casts, so I used this: template <typename Enumeration> auto as_integer(Enumeration const value) -> typename std::underlying_type<Enumeration>::type { return static_cast<typename std::underlying_type<Enumeration>::type>(value); }
Thanks. Also, I have the same question as @DanNissenbaum
|

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.