Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them, it only takes a minute:

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])'

share|improve this question
2  
You seem to be using elements of an uninitialized std::array in the initialization of said array. – chris Feb 4 '14 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. – Dan Nissenbaum Feb 4 '14 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. – Crysis Feb 5 '14 at 5:42

1 Answer 1

up vote 2 down vote accepted

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")  
};
share|improve this answer
    
Thanks. I'm about to try this out. I have a typedef set up; that's why my code says group:: and metalStat::. – Crysis Feb 4 '14 at 4:59
    
@Crysis Also, you can replace as_integer with static_cast<int>, as an enum class's underlying type is int by default. – user1508519 Feb 4 '14 at 5:01
    
I'm new to uniform initialization - can you explain why the two sets of curly braces are necessary? – Dan Nissenbaum Feb 4 '14 at 5:02
    
@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); } – Crysis Feb 4 '14 at 5:05
    
Thanks. Also, I have the same question as @DanNissenbaum – Crysis Feb 4 '14 at 5:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.