tags:

views:

702

answers:

5

I have the following use case, a struct with some boolean and int variables

struct a {

    int field1;
    bool field2;
    bool field3;

};

I am refactoring this code, and writing a constructor for the struct , the problem is the default initialization of fields.

I am not criticizing any language construct here, but ideally I would want null to be part of the language itself

i mean I should be able to define for struct a as

a : field1(null.int), field2(null.bool), field3(null.bool) {}

C++ does not allow it since null.int or null.bool are not defined. Is the only way to do in C++ is

a: field1(-1), field2(false), field3(false) {}
+8  A: 

You can do

struct a {
    a():field1(), field2(), field3() { }
    int field1;
    bool field2;
    bool field3;
};

And all fields will be zero and false respectively. If you want to say that the fields have an indeterminate value, i'm afraid you have to use other techniques. One is to use boost::optional:

struct a {
    a():field1(int()), field2(bool()) { }
    optional<int> field1;
    optional<bool> field2;
    optional<bool> field3;
};

Leaves field3 indeterminate. Access the values with *field_name. Test for a none value with field == boost::none or if(field) { ... }.

Johannes Schaub - litb
+3  A: 

A boolean has two states. That's what makes it a boolean. So, in any strongly typed language, a boolean is either true or false.

An integer in c/c++ (and java) is the direct binary representation of a number. You can assign one value of that number to mean "this number has no value", but this does not make sense in all situations - and if the language were to take that into account, every math operation would have to be preceded by a check - it would really slow things down.

Bottom line: If you want a weak type system, use another language.

gnud
+2  A: 

You seem to want to be able to say the fields are in an undefined state.

This goes against the principles of a strongly types language (such as C++) so you are out of luck.
If you want to check if something has been defined of not you need to explicitly track it yourself. You could potentially use pointers to solve your problem but I don't personally think that would be a good idea.

Maybe if you tried to explain the real problem you are trying to solve we could provide better advice.

Martin York
+4  A: 

If you're looking for a type with values {true, false, null}, that type is not bool. However, boost::optional<bool> is such a type. In the same way, boost::optional<int> can hold any int, or no int at all.

MSalters
+1  A: 

It's the c++ way not to pay for anything you don't use and default initialization and the ability to have uninitialized bool is something that many people won't need.

If you really want this kind of behavior you can build a nullable version of the type you are working with. Something along the lines:

class NullBool {
  bool m_null;
  bool m_value;
  public:
  NullBool() : m_null(true) {}
  NullBool(bool value) : m_null(false), m_value(value) {}
  void isNull() const {
    return m_null;
  }
  void value() const {
    return m_value;
  }
  ...
  // lots of operations
  ...
};

This should probably be built as a template so it works for more types out of the box. And since it's your own type you can easily make the default constructor to make it null by default.

Laserallan
that template would be ... boost::optional<T> ?
xtofl
Definitely seems so, I didn't know about it until litb edited his post to mention it :)
Laserallan