Namespaces
Variants

std::ios_base:: register_callback

From cppreference.net
void register_callback ( event_callback function, int index ) ;

注册一个用户自定义函数,该函数将被 imbue() std::basic_ios::copyfmt() ~ios_base() 调用。每次都会调用每个已注册的回调函数:事件类型( event 类型的值)作为其第一个参数传递,可用于区分调用者。

回调函数按照注册的相反顺序被调用(换言之, register_callback() 会将回调函数对压入回调栈)。如果从回调函数内部调用 register_callback() 来添加新回调,新回调仅会在下一个事件时被调用。

用户自定义回调函数不允许抛出异常。

目录

参数

function - 事件触发时调用的函数,以类型为 event_callback 的函数指针形式提供
index - 将传递给该函数的自定义参数

返回值

(无)

注释

注册后,回调无法被注销:在流对象的整个生命周期内,它将始终作为其组成部分存在。若需改变回调行为,可通过 iword() pword() 进行控制。

如果同一个函数被多次注册,它将被多次调用。

存储于回调函数中的整数值通常是通过 xalloc() 获取的索引值。

示例

演示如何使用 register_callback 来更新由自定义输出操作符使用的、依赖于区域设置的缓存值。

#include <functional>
#include <iostream>
#include <locale>
// 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';
}

输出:

Memory exhausted : 2,295,079,096
Speicher erschöpft : 3,139,423,551
メモリーが足りません : 3,837,351,114
Память исчерпана : 3,742,732,851