代码如下:
struct lex_compare {
bool operator() (const weak_ptr<int> &lhs, const weak_ptr<int> &rhs)const {
return *lhs.lock() < *rhs.lock();
}
};
int main(){
set<weak_ptr<int>,lex_compare> intset;
intset.insert(make_shared<int>(1));
cout << "intset size:" << intset.size() << endl; //1
cout << "Does 1 exist?"<< intset.count(make_shared<int>(1))<<endl; // failed
}
我想知道如何count/find weak_ptr<int>存储在 intset是否有更好的方法可以完成同样的工作?
最佳答案
您不能将临时 shared_ptr 插入弱指针集,因为从这个存储的弱指针指向已删除的内存的意义上讲,这是内存泄漏。
intset.insert(make_shared<int>(1));
// after this instruction shared_ptr destructor frees the memory
这就是为什么您无法在集合中找到它的原因 - 因为 *lhs.lock() UB 在吗?
参见 weak_ptr::lock doc .
您需要以这种方式制作 òrder 运算符:
struct lex_compare {
bool operator() (const weak_ptr<int> &lhs, const weak_ptr<int> &rhs)const {
auto lptr = lhs.lock(), rptr = rhs.lock();
if (!rptr) return false; // nothing after expired pointer
if (!lptr) return true; // every not expired after expired pointer
return *lptr < *rptr;
}
};
这意味着 - 你需要有这个 shared_ptr sowmewhere 来计算它:
int main(){
set<weak_ptr<int>,lex_compare> intset;
auto shared1 = make_shared<int>(1);
intset.insert(shared1);
cout << "intset size:" << intset.size() << endl; //1
cout << "Does 1 exist?"<< intset.count(make_shared<int>(1))<<endl; // failed
}
有了上面的内容 - 你的计数就可以了。
还考虑将 shared_ptr 保留在集合中...
[更新]
marko 在评论中指出了有效的问题。 std::weak_ptr 根本不能以您使用它的方式用作键。只有当你能确保指向的值永远不会改变或者指针本身永远不会过期时。看这个例子:
set<weak_ptr<int>,lex_compare> intset;
auto shared1 = make_shared<int>(1);
intset.insert(shared1);
cout << "Does 1 exist?"<< intset.count(make_shared<int>(1))<<endl; // works
shared1.reset();
cout << "Does 1 exist?"<< intset.count(make_shared<int>(1))<<endl; // failed
另一个例子:
set<weak_ptr<int>,lex_compare> intset;
auto shared1 = make_shared<int>(1);
intset.insert(shared1);
cout << "Does 1 exist?"<< intset.count(make_shared<int>(1))<<endl; // works
*shared1 = 2;
cout << "Does 1 exist?"<< intset.count(make_shared<int>(1))<<endl; // failed
您可以保留 std::shared_ptr 以防止指针超出集合过期 - 并且 std::shared_ptr 具有 operator < - 但这个运算符比较指针本身 - 而不是指向的值 - 所以更好的是 std::set<std::shared_ptr<int>> - 但最好的是 std::set<int>
或更改std::set<...> --> std::vector<std::weak_ptr<int>> - 并使用 count_if -- 参见:
vector<weak_ptr<int>> intset;
auto shared1 = make_shared<int>(1);
intset.push_back(shared1);
cout << "Does 1 exist?"<< count_if(begin(intset), end(intset),
[](auto&& elem)
{
auto ptr = elem.lock();
return ptr && *ptr == 1;
});
或用std::set<std::shared_ptr<int>> :
set<shared_ptr<int>> intset;
auto shared1 = make_shared<int>(1);
intset.insert(shared1);
// if you can ensure shared1 value will not change:
cout << "Does 1 exist?"<< intset.count(shared1);
// if not - use count_if - the slower than std::count
cout << "Does 1 exist?"<< count_if(begin(intset), end(intset),
[](auto&& ptr)
{
return ptr && *ptr == 1;
});
关于c++ - 一组 weak_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32668742/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t
我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat
这是我在ChefRecipe中的一blockRuby:#ifdatadirdoesn'texist,moveoverthedefaultoneif!File.exist?("/vol/postgres/data")execute"mv/var/lib/postgresql/9.1/main/vol/postgres/data"end结果是:Executingmv/var/lib/postgresql/9.1/main/vol/postgres/datamv:inter-devicemovefailed:`/var/lib/postgresql/9.1/main'to`/vol/post