Compiling code with compare using gcc-c++ 8.0.1-0.8 causes error /usr/include/c++/8/bits/stl_tree.h: In instantiation of 'class std::_Rb_tree<std::shared_ptr<i2p::tunnel::InboundTunnel>, std::shared_ptr<i2p::tunnel::InboundTunnel>, std::_Identity<std::shared_ptr<i2p::tunnel::InboundTunnel> >, i2p::tunnel::TunnelCreationTimeCmp, std::allocator<std::shared_ptr<i2p::tunnel::InboundTunnel> > >': /usr/include/c++/8/bits/stl_set.h:133:17: required from 'class std::set<std::shared_ptr<i2p::tunnel::InboundTunnel>, i2p::tunnel::TunnelCreationTimeCmp>' /builddir/build/BUILD/i2pd-git-2.18.0/libi2pd/TunnelPool.h:117:68: required from here /usr/include/c++/8/bits/stl_tree.h:452:21: error: static assertion failed: comparison object must be invocable with two arguments of key type static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{}, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Full log on COPR: https://copr-be.cloud.fedoraproject.org/results/supervillain/i2pd/fedora-rawhide-x86_64/00709308-i2pd-git/builder-live.log Code: > https://github.com/PurpleI2P/i2pd/blob/openssl/libi2pd/TunnelPool.h#L117 std::set<std::shared_ptr<InboundTunnel>, TunnelCreationTimeCmp> m_InboundTunnels; > https://github.com/PurpleI2P/i2pd/blob/openssl/libi2pd/TunnelBase.h#L60 struct TunnelCreationTimeCmp { bool operator() (const std::shared_ptr<const TunnelBase> & t1, const std::shared_ptr<const TunnelBase> & t2) const { if (t1->GetCreationTime () != t2->GetCreationTime ()) return t1->GetCreationTime () > t2->GetCreationTime (); else return t1 < t2; }; }; Changes regarding on GCC bug #83102 doesn't solved problem.
The problem is that the InboundTunnel and OutboundTunnel types are incomplete, so it's not possible to verify that the comparison function is valid. That code is very inefficient, as it will create new temporary shared_ptr objects for every comparison in the sets, requiring four atomic reference count updates for every comparison. Making the comparison function accept the derived types would avoid that, and fix the compilation error too: struct TunnelCreationTimeCmp { template<typename T> bool operator() (const std::shared_ptr<T>& t1, const std::shared_ptr<T>& t2) const { if (t1->GetCreationTime () != t2->GetCreationTime ()) return t1->GetCreationTime () > t2->GetCreationTime (); else return t1 < t2; } };
--- a/libi2pd/TunnelBase.h +++ b/libi2pd/TunnelBase.h @@ -59,7 +59,8 @@ namespace tunnel struct TunnelCreationTimeCmp { - bool operator() (const std::shared_ptr<const TunnelBase> & t1, const std::shared_ptr<const TunnelBase> & t2) const + template<typename T> + bool operator() (const std::shared_ptr<T> & t1, const std::shared_ptr<T> & t2) const { if (t1->GetCreationTime () != t2->GetCreationTime ()) return t1->GetCreationTime () > t2->GetCreationTime (); https://github.com/PurpleI2P/i2pd/commit/4af0caa50639c9c080034b2ea8239eb7e06f0ba3 Thank you, issue resolved.