Question

I have about 20 private bools within a class in C++. I would like for these to be publicly accessible using a (public) function.

Is it possible to pass the name of a (private) variable as an argument to such a function? For example,

void setTrue(std::string varName)
{
    someFunctionToConvertStringToVariable = true;
}

Alternatively, I think that

void setTrue(std::string varName)
{
    if (varName == "boolA")
    {
        boolA = true;
    }
    else if (varName == "boolB")
    {
        boolB = true;
    }
}

would work, and could use a switch(varName) to reduce the number of LOC needed.

Another option would presumably be to just make all of the booleans public, and then access them using myClass.boolA = true; from the calling program - I'm not sure this is the best idea, but it's certainly simpler, and so that's an argument in its favour.

Is there a generally accepted/best way to do this type of thing? Have I just set up the problem badly and is there a much smarter way to go about this? Perhaps an enum of varnames would allow passed variables to be checked, but I don't think that would necessarily make it easier to set the boolean.

Was it helpful?

Solution

You can use a std::map<std::string, bool> to store the bool values. Then,

void setTrue(std::string varName)
{
    // Add some checks to make sure that varName is valid.

    varNames[varName] = true;
}

OTHER TIPS

If the list of these variables isn't going to change, I can propose you to use enumeration and overriden subscript operator:

enum MyBools
{
    First = 0,      
    BoolA = First,       
    BoolB,       
    //...
    Bool20,     
    Last = Bool20,
}    

class MyIndexedBools
{
private:
    bool m_Bools[MyBools::Last + 1];

public:
    bool& operator[] (MyBools index);
};

bool& operator[] (MyBools index);
{
    if (index < First || index > Last)
         throw "error";

    return m_Bools[index];
}

It is not extensible in runtime but will give you better compile-time safety than maps.

Your second solution is the way to go here, however I think that the switch case does not reduce the LOC, beside the fact that it won't work with an `std::string!

void setTrue(const std::string& varName)
{
    if (varName == "boolA")
    {
        boolA = true;
    }
    else if (varName == "boolB")
    {
        boolB = true;
    }
}

VS:

void setTrue(const std::string& varName)
{
    switch(str2int (varName))
    {
    case str2int ("boolA"):
        boolA = true;
        break;
    case str2int("boolB"):
        boolB = true;
        break;
    default: 
        assert (false);
    }
}

And keep in mind that if you do not want to modify the passed parameter it is good practice to pass it as const! In that case I'd personally pass it as const reference.

Twenty bool is a lot, indeed.

Instead, I would advise using a bitset indexed with constants (using enum for example). Assuming C++11:

class SomeClass {
public:
    enum class Flag: size_t {
        Flag1,
        Flag2,
        Flag3,
        ...,
        Flag20
    };

    bool get_flag(Flag f) const { return _flags.test(size_t(f)); }

    void set_flag(Flag f, bool value) { _flags.set(size_t(f), value); }

private:
    std::bitset<size_t(Flag20) + 1> _flags;
}; // class SomeClass

Note: all out of range accesses are carried out by bitset, handy isn't it ?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top