# std::ios_base::register_callback

< cpp‎ | io‎ | ios base

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 <iostream>
    #include <locale>
    #include <functional>

    // 缓存本地环境限定的消息及其哈希
    typedef std::pair<std::string, std::size_t> cache_t;

    // 从本地环境填充缓存的消息及其哈希
    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);
    }

    // 若本地环境更改则更新缓存
    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());
        }
    }

    // 注册 pword() 中的缓存并设置回调
    struct CacheSetup
    {
        CacheSetup(std::ostream& os, std::ios_base::event_callback f, cache_t* cache)
        {
            int index = std::ostream::xalloc();
            os.pword(index) = cache; // 设置指针指向流中的缓存
            os.register_callback(f, index); // 存储回调和指针的下标
            update_cache(*cache, os.getloc()); // 初始化缓存
        };
    };

    // 某定制类
    struct S { };
    // 某定制类的 operator<< 需要到被哈希消息的快速访问
    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