0

I wrote a class with an overloaded conversion operator to do something, if a member variable is readed (e.g. calculate a checksum, read a stored value from an EEPROM, etc).

This works fine, if a simple data type is used.

template <typename T>
class Storage
{
private:
  
public:
  T var;
  
  Storage(const T &value)
  : var(value)
  { }

  // 'read' variable
  operator const T& () const 
  { 
    // ... do something
    
    return var; 
  }

  // 'write' variable
  const T& operator = (const T &value)
  { 
    var = value;
    
    // ... do something
    
    return var; 
  }
}; 

Storage<int> setupValue(34500);
int test1 = setupValue;

If I use a struct instead, it also works, when reading the whole struct:

typedef struct
{
  int      min;
  int      start;
  int      max;
  
} setup_t;
  
Storage<setup_t> setupValues({35100, 39000, 42000});
setup_t test2 = setupValues;

But, when I read only a single member variable of that struct, the overloaded operator functions are not called:

int test3 = setupValues.var.start;

Is there a way, to always call the overloaded operator function?

The 'do something' part should be executed, even if I read only a member of the setup struct.

Klaus
  • 1
  • 2
  • 1
    There is no `operator()` here. There is `operator const T&`. I recommend against either one. Write a `get()` function instead, and make `var` private. – n. m. could be an AI Mar 23 '23 at 11:38
  • If I make `var` private (which is for sure a good idea) and use a `get()` function, how could I select which member I want to read from my `setup_t` struct? The class `Storage` should be flexible to be used for different variable types and structures. – Klaus Mar 23 '23 at 13:45
  • @Klaus your title says *address-of* operator (`operator&`), but your text (possibly) mentions the *call* operator (`operator()`) instead, but there are no such operators in the code, all I see are a *conversion* operator (`operator `) and an *assignment* operator (`operator=`). I think you need to do some more reading about what `operators` actually are and how they work. – Remy Lebeau Mar 23 '23 at 15:36
  • @Klaus are you looking for something like this? `operator const int& () const { ... return var.start; } Storage& operator = (const int &value) { var.start = value; ... return *this; }` If your `T` has multiple members of its own, you can use a [member pointer as a template argument](https://stackoverflow.com/questions/6880832/) so the user can tell `Storage` which member to act on, eg: `Storage setupValues(...);` – Remy Lebeau Mar 23 '23 at 15:47
  • There is no `operator&` there either. There is `operator const T&`. It is a convection operator. It converts `*this` to `const T&`. If you replace it with a `get` function that returns `const T&`, you write something like `setupValues().get().start`. – n. m. could be an AI Mar 23 '23 at 15:52
  • Sorry for the confusing initial title, now I changed it to ... "conversion operator" ... – Klaus Mar 24 '23 at 12:58

1 Answers1

0

According to one of the above suggestions, I made a implementation with a get() function:

template <typename T>
class Storage
{
private:
   T var; 

public:

  Storage(const T &value)
  : var(value)
  { }

  // 'read' variable
  const T& get(void)
  {
    // ... do something
    
    return var;
  }
};  

I can now read a single member of the setup struct and run the "do something" part in the get() function, in front oft it:

int test1 = setupValues.get().max;
Klaus
  • 1
  • 2