Templates as function arguments by reference

Hello everybody,

I have some trouble with templace structs. What I would like to do is the following :
I read values from a settings file (key=value pairs). These values can be present in the file or not. These values can be int, bool, string, ...

So instead to give special values for non present values, I made struct like this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <typename T> struct value_t {
private:
  T value;

public:
  bool present;

  value_t () { present = false; };
  value_t<T> & operator = (const T &v) {
    value = v;
    return *this;
  }
  operator T () const {
    return value;
  }
};


this allows me to build objects like value_t<bool> that hold a boolean in addition to an attribute telling whether it is present of not.
however, by redefining the operatons, it let me use them like standard bool, int, ...

1
2
value_t<bool> b = true;
bool is_true = b;


The problem is that I did not succeed passing value_t<> to functions by reference.

Example :
1
2
3
4
5
6
7
8
void func(...., bool &error)
{ ... }

I can't do something like :

value_t<bool> err = false;

func(..., err); 


Can you help me on this ?

Thanks in advance
You cannot do that. func() expects to be able to modify error (it takes it by reference, not value or const reference). The only way to make this work is to make error a template argument.
Thanks for the quick reply. I did not understand well the response but ...
I thought if I defined a custom conversion between value_t<bool> and bool, then passing a value_t<bool> to a function taking a bool would trigger the implicit conversion. That's currently what happens.

Why this does not work for references. I tried to redefine the & operator but still does not work.

(I have little experience with templates)

Can I get whatI want if I changed the argument of the function to a bool * ?

Thanks
Last edited on
To do this:

1
2
3
4
5
void func(...., bool &error)
{ ... }

value_t<bool> err = false;
func(..., err); 


you need this:

1
2
3
  operator T& () {
    return value;
  }

Hi,

Thanks for this. With your help and some changes the following code does what I want :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <typename T> struct value_t {
private:
  T value;

public:
  bool present;

  value_t () { present = false; };
  value_t<T> & operator = (const T &v) {
    value = v;
    return *this;
  }
  operator const T & () const {
      return value;
  }
  operator T & () {
    return value;
  }
};


I added your code and replaced 'operator T () const' by 'operator const T & () const'

This seems to wotk with all of my code, including '<<' operator and '&' arg by reference

Thanks
which is actually reinvent boost::optional http://www.boost.org/doc/libs/1_46_1/libs/optional/doc/html/index.html (nobody understands boost::optional?)
jsmith is correct. Adding a reference conversion operator will allow you to pass the object to the function.

However, this breaks the usage of this class. You don't know if the value was set of not, so you have no idea whether to set the "present" flag. The only way to make your class work is to actually pass the class itself to the function (not a reference to it's internal value) so that the assignment operator can set the "present" flag.

And coder777 is absolutely correct. boost::optional has already been invented, tested and known to work across numerous compilers and platforms.
You're absolutely right. Passing the argument as reference will break the present flag consistency. I'll pass the entire class.

The purpose of my program is to make a Qt4 theme so I can't depend on boost.

Thanks
Topic archived. No new replies allowed.