void register_callback( event_callback function, int index ); |
Registers a user-defined function which will be called by imbue()
, std::basic_ios::copyfmt()
and ~ios_base()
. Every registered callback is called every time: the event type (a value of type event
) is passed as its first argument, and may be used to distinguish between the callers.
The callbacks are called in the reverse order of registration (in other words, register_callback()
pushes a callback pair on the callback stack). If register_callback()
is called from within a callback function to add a new callback, the new callback is only called on the next event.
The user-defined callback function is not allowed to throw exceptions.
Parameters
function | - | the function which will be called on event, supplied as a function pointer of type event_callback |
index | - | custom parameter which will be passed to the function |
Return value
(none).
Notes
Once registered, a callback cannot be deregistered: it remains a part of the stream object for the rest of its lifetime. If the behavior of a callback needs to change, it may be controlled through iword()
or pword()
.
If the same function is registered multiple times, it is called multiple times.
The integer value that is stored together with the callback is typically an index obtained from xalloc()
.
Example
demonstrates the use of register_callback to update locale-dependent cached values that are used by a custom output operator.
#include <iostream> #include <locale> #include <functional> // cached locale-specific message and its hash typedef std::pair<std::string, std::size_t> cache_t; // populate the cached message and its hash from the locale void update_cache(cache_t& cache, std::locale loc) { auto& fct = std::use_facet< std::messages<char> >(loc); std::messages_base::catalog cat = fct.open("sed", loc); cache.first = cat < 0 ? "" : fct.get(cat, 0, 0, "Memory exhausted"); cache.second = std::hash<std::string>()(cache.first); } // update the cache if the locale changed void true_callback(std::ios_base::event evt, std::ios_base& str, int idx) { if (evt == std::ios_base::imbue_event) { cache_t* ptr = static_cast<cache_t*>(str.pword(idx)); update_cache(*ptr, str.getloc()); } } // registers the cache in pword() and sets up the callback struct CacheSetup { CacheSetup(std::ostream& os, std::ios_base::event_callback f, cache_t* cache) { int index = std::ostream::xalloc(); os.pword(index) = cache; // store pointer to cache in the stream os.register_callback(f, index); // store callback and the index to the pointer update_cache(*cache, os.getloc()); // initialize cache }; }; // some custom class struct S { }; // some custom class's operator<< that needs fast access to hashed message std::ostream& operator<<(std::ostream& os, const S&) { static cache_t cache; static CacheSetup setup(os, true_callback, &cache); return os << cache.first << " : " << cache.second; } int main() { std::locale loc("en_US.utf8"); S s; std::cout.imbue(loc); std::cout << s << '\n'; std::cout.imbue(std::locale(loc, new std::messages_byname<char>("de_DE.utf8"))); std::cout << s << '\n'; std::cout.imbue(std::locale(loc, new std::messages_byname<char>("ja_JP.utf8"))); std::cout << s << '\n'; std::cout.imbue(std::locale(loc, new std::messages_byname<char>("ru_RU.utf8"))); std::cout << s << '\n'; }
Output:
Memory exhausted : 2,295,079,096 Speicher erschöpft : 3,139,423,551 メモリーが足りません : 3,837,351,114 Память исчерпана : 3,742,732,851
Please login to continue.