首页 > 解决方案 > c++ std::map `emplace` 和 `emplace_back` 重载

问题描述

我的问题如下:

我有一对功能:

using my_map_t = std::map<int, double>;
using my_map_iterator_t = my_map_t::iterator;
my_map_t my_map;

...

void func1(int a, double b) {
    ...
    my_map.emplace(a, b);
    ...
}

void func2(int a, double b, my_map_iterator_t hint) {
    ...
    my_map.emplace_hint(hint, a, b)
    ...
}

我想避免代码重复并尽可能快。我发现的一种可能的解决方案是以下

template <bool has_hint>
func(int a, double b, my_map_iterator_t hint=my_map.end() /*unused if has_hint=false*/) {
    ...
    if constexpr(has_hint) 
        my_map.emplace_hint(hint, a, b);
    else
        my_map.emplace(a, b);
    ...
}

但不幸的是,我在目标机器上没有 c++17 编译器。

我正在考虑使用默认参数作为提示,这样emplace_hint将具有完全相同的效果emplace。但是我想象地图被实现为(RB)树,因此所需的迭代器将每次计算(可能作为“中值迭代器”)

你能给我一个优雅的出路吗?

标签: c++data-structuresstdstdmap

解决方案


您可以使用常用方法进行因式分解:

template <typename F>
void func_impl(int a, double b, F emplacer)
{
// ...
    emplacer(my_map, a, b);
// ...
}

void func1(int a, double b) {
    func_impl(a, b, [](auto& my_map, int a, double b) { my_map.emplace(a, b); });
}

void func2(int a, double b, my_map_iterator_t hint) {
    func_impl(a, b, [&hint](auto& my_map, int a, double b) { my_map.emplace_hint(a, b, hint); });
}

推荐阅读