On 5/03/2021 5:26 pm, Nicholas Neumann wrote:
Peter Dimov wrote:
If you're going to use a client-supplied callback, the most straightforward one would just return a shared_ptr<FILE> (or the appropriate equivalent). Then both opening and closing are under the callback's control.
That's interesting to think about. A simultaneous pro and con I see is that the callback now has to deal with how to open and close a file, which was an implementation detail of the backend before. If you want or need that level of control, it is useful. But a callback which asks "close the file?" only has to take a path and return a boolean, leaving most of the concerns to the backend. Both allow for any caching strategy. Either one works for me so if the shared_ptr<FILE> approach solves problems for others that the boolean approach does not, I'd be just as happy with it.
To fix that, you could have the callback return void and take the shared_ptr as a parameter instead -- keeping it alive keeps the file open. The callback would only be called when the framework needs to open a new file (or a new pointer to an existing file), not when re-using an existing pointer. The problem is that now both sides have to keep track of this pointer and its context (inside the framework, as a weak_ptr; outside, as a shared_ptr), which has some overhead, especially if the logging system is intended to be multi-thread-safe. Depending on where the callback is attached and how it's used, this may be straightforward or complicated. (Also, using FILE directly ties the implementation to C++ iostreams; it would be better to use an abstraction instead.)