Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ try_emplace的惰性参数评估?_C++_C++17 - Fatal编程技术网

C++ try_emplace的惰性参数评估?

C++ try_emplace的惰性参数评估?,c++,c++17,C++,C++17,我需要一个对象,该对象可以用map包装try_emplace的惰性初始化(实际上,只有在需要时才调用工厂类型的函数),以便在try_emplace中转换为ok: std::map<std::string, bool> cache_; cache_.try_emplace("hello", lazy_wrapper([]{return true;})); std::映射缓存; cache.try_emplace(“hello”,lazy_包装器([]{return

我需要一个对象,该对象可以用map包装try_emplace的惰性初始化(实际上,只有在需要时才调用工厂类型的函数),以便在
try_emplace
中转换为ok:

std::map<std::string, bool> cache_;
cache_.try_emplace("hello", lazy_wrapper([]{return true;}));
std::映射缓存;
cache.try_emplace(“hello”,lazy_包装器([]{return true;}));
或许

std::映射缓存;
cache_u.try_uemplace(“hello”,[{return true;});

我想这应该是可能的,但主要是为了寻找一种现成的解决方案(例如,std/
boost
),而不是我自己的包装机。

以下是我在几分钟内拼凑出来的一个手工解决方案,可以完成这项工作,但我主要是在寻找某种现成的解决方案:

template<class F>
struct lazy_wrap {
    F f_;
    lazy_wrap(F&& f) : f_(f) {}
    template<class T>
    operator T() {
        return f_();
    }
};
模板
结构惰性包装{
F_;
惰性包装(F&&F):F(F){}
模板
算子T(){
返回f_();
}
};

您真的需要包装器吗?您可以这样做:

// C++20
if (!cache_.contains("hello"))
    cache_.emplace("hello", [] { return true; });

// pre C++20
if (cache_.count("hello") == 0)
    cache_.emplace("hello", [] { return true; });

简单、清晰、不令人头痛。

由于没有简单的功能,您最终必须自己实现try-emplace逻辑

template<typename Map, typename Key, typename Func>
auto lazy_try_emplace(Map &map, const Key &key, Func f)
{
    auto it = map.find(key);
    if(it == map.end())
      return map.emplace(key, f());
    return std::pair(it, false);
}
模板
自动延迟尝试模板(映射和映射、常量键和键、函数f)
{
auto it=map.find(键);
if(it==map.end())
返回map.emplace(键,f());
返回std::pair(it,false);
}

是的,这会查找元素两次,但是如果不真正成为
std::map
实现的一部分,就无法避免这种情况(这就是
try\u emplace
存在的原因)。通过替换
map.find
map.lower\u bound
,更改条件测试以查看键是否不等于
key
,并使用该迭代器使用
emplace\u hint

您尝试了什么?我尝试提供lambda裸体,即ofc。我没有编译。我想创建一个将要转换的类类型很容易,但正如我所说的,如果已经存在现成的解决方案,我最感兴趣。唉,在一个完美的(转发)世界里。就惰性而言,你的意思是除非键不在映射中,否则函数不会被调用吗?@Nicolas that Corrective这将每次计算
f
以得到
t
,我不会称之为“惰性”哦,这是针对
std::map
,not
std::map
这是一个双重查找。正如你所说,我真的不需要一个包装器(map.find也可以),但这样一行代码更具表现力。同样的道理,我们一开始也不需要试射。
template<typename Map, typename Key, typename Func>
auto lazy_try_emplace(Map &map, const Key &key, Func f)
{
    auto it = map.find(key);
    if(it == map.end())
      return map.emplace(key, f());
    return std::pair(it, false);
}