C++ c++;std::映射'emplace'和'emplace_back'重载

C++ c++;std::映射'emplace'和'emplace_back'重载,c++,data-structures,std,stdmap,C++,Data Structures,Std,Stdmap,我的问题如下: 我有一对函数: 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_

我的问题如下:

我有一对函数:

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)
    ...
}
使用my_map\u t=std::map;
使用my_map_迭代器\u t=my_map_t::迭代器;
我的地图不是我的地图;
...
无效函数1(整数a,双精度b){
...
我的地图位置(a,b);
...
}
void func2(int a,double b,my\u map\u iterator\u t 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);
    ...
}
模板
func(int a,double b,my\u-map\u迭代器\u-t-hint=my\u-map.end()/*如果有\u-hint=false,则未使用*){
...
if constexpr(有提示)
我的地图。放置提示(提示,a,b);
其他的
我的地图位置(a,b);
...
}
但不幸的是,我在目标机器上没有c++17编译器

我正在考虑为hint使用一个默认参数,这样
emplace\u hint
将具有与
emplace
完全相同的效果。然而,我想象映射被实现为(RB)树,因此所需的迭代器将被每一次计算(可能作为“中间迭代器”)


你能给我一个优雅的解决方法吗?

你可以用一种常见的方法进行分解:

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); });
}
模板
void func_impl(int a,double b,F emplacer)
{
// ...
emplacer(我的地图,a,b);
// ...
}
无效函数1(整数a,双精度b){
func_impl(a,b,[](自动&我的地图,int a,double b){my_地图.安放(a,b);});
}
void func2(int a,double b,my\u map\u iterator\u t hint){
func_impl(a,b,[&hint](自动和我的映射,int a,double b){my_映射。放置提示(a,b,hint);});
}

您可以使用一种常用方法进行分解:

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); });
}
模板
void func_impl(int a,double b,F emplacer)
{
// ...
emplacer(我的地图,a,b);
// ...
}
无效函数1(整数a,双精度b){
func_impl(a,b,[](自动&我的地图,int a,double b){my_地图.安放(a,b);});
}
void func2(int a,double b,my\u map\u iterator\u t hint){
func_impl(a,b,[&hint](自动和我的映射,int a,double b){my_映射。放置提示(a,b,hint);});
}

只使用
func(int a,double b,my\u map\u iterator\u t hint=my\u map.end())有什么问题?如果暗示是错误的,你不会真的失去任何东西。它认为这是一个单独的额外比较,可能是一个节点遍历。嗯,这是一个非常关键的性能特性,我希望最常见的行为是没有提示的行为。您是否实际测量了是否有命中?另外,您是否需要有序数据
std::unordered_map
理论上,如果您不需要排序,它的性能会更好。@NathanOliver,还有一个比较,然后对
my_map.end()
进行了无用的调用。不幸的是,我需要有序的数据!但是,如果不需要如此高的性能,这是一个很好的建议。只使用
func(int a,double b,my\u map\u iterator\u t hint=my\u map.end())有什么错?如果暗示是错误的,你不会真的失去任何东西。它认为这是一个单独的额外比较,可能是一个节点遍历。嗯,这是一个非常关键的性能特性,我希望最常见的行为是没有提示的行为。您是否实际测量了是否有命中?另外,您是否需要有序数据
std::unordered_map
理论上,如果您不需要排序,它的性能会更好。@NathanOliver,还有一个比较,然后对
my_map.end()
进行了无用的调用。不幸的是,我需要有序的数据!然而,如果不需要如此高的性能,这是一个很好的建议。