You can return a proxy object to operator[] , and not just a reference to the contained value. Then you can set the flag in the proxy when it is assigned (that is, when the intermediary operator = is called). Then you can use the proxy destructor if it has never been assigned. Of course, you need to create a proxy server instance using boolean, indicating whether you want to require an assignment (no value exists) or not (the value is already set).
Note that it is generally considered improper practice to throw a destructor. In particular, the proxy destructor should not be thrown if it was called due to another exception (for example, an error between finding keys and assigning values). You will probably want to skip the throw from the proxy destructor if the exception is already in flight, and you can detect this condition with std::uncaught_exception() .
And finally, I will talk about this article about uncaught_exception() : http://www.gotw.ca/gotw/047.htm
It uses two arguments against using this function. First, it can sometimes return true when it is actually safe to throw. I affirm that we can live with this in your case, because we are trying to provide a security audit, and if we are sometimes not able to provide a security audit, then we are not much worse than before. And if we can agree that sometimes the check is not performed in order, then the second argument (โmoralโ) in the article can also be ignored (since your proxy will not have two different error handling mechanisms, it will have one that is usually effective but not always).
source share