libzypp (and anything using it) fails to build with clang due to std::mem_fn
Closed this issue · 5 comments
libzypp and anything using libzypp's <zypp/Arch.h>
header fails to build with clang because clang is stricter about std::mem_fn
than gcc, rejecting std::mem_fn
use on a virtual member.
/home/bero/abf/libzypp/BUILD/libzypp-17.31.18/zypp/Arch.h:137:64: error: no matching function for call to 'mem_fn'
return str::join( make_transform_iterator( cset.begin(), std::mem_fn(&Arch::asString) ),
^~~~~~~~~~~
/usr/bin/../lib64/gcc/x86_64-openmandriva-linux-gnu/13.1.1/../../../../include/c++/13.1.1/functional:237:5: note: candidate template ignored: couldn't infer template argument '_Tp'
mem_fn(_Tp _Class::* __pm) noexcept
^
The issue is not virtual functions but overload resolution does not work here. We have a static vs non static asString, which should be selectable via templates...
Because the type of the non static one should be const std::string & (Arch::*memfn)( ) const
where the static one is std::string & (*memfn)( )
And the signature of mem_fn is:
template<typename _Tp, typename _Class>
_GLIBCXX20_CONSTEXPR
inline _Mem_fn<_Tp _Class::*>
mem_fn(_Tp _Class::* __pm) noexcept
{
return _Mem_fn<_Tp _Class::*>(__pm);
}
So the static overload should not even be considered here... i guess we can work around it though
But note that compiling libzypp with clang is currently not supported
Does that solve your problem?
--- zypp/Arch.h
+++ zypp/Arch.h
@@ -134,8 +134,9 @@ namespace zypp
/** */
static std::string asString( const CompatSet & cset )
{
- return str::join( make_transform_iterator( cset.begin(), std::mem_fn(&Arch::asString) ),
- make_transform_iterator( cset.end(), std::mem_fn(&Arch::asString) ) );
+ const std::string & (Arch::*memfn)( ) const = &Arch::asString;
+ return str::join( make_transform_iterator( cset.begin(), std::mem_fn( memfn ) ),
+ make_transform_iterator( cset.end(), std::mem_fn( memfn ) ) );
}
public:
Thanks, that does fix it. libzypp itself still doesn't build with clang (at least clang 16) because
/home/bero/abf/libzypp/BUILD/libzypp-17.31.18/zypp-tui/output/Out.h:450:36: error: integer value 255 is outside the valid range of values [0, 3] for this enumeration type [-Wenum-constexpr-conversion]
static constexpr Type TYPE_ALL = TypeBit(0xff);
^
1 warning and 1 error generated.
Clang realizes the enum only takes values of 0 to 3, so doesn't like the 0xff. Setting it to 3 (which for now should do the same thing) fixes it.
Clang realizes the enum only takes values of 0 to 3, so doesn't like the 0xff. Setting it to 3 (which for now should do the same thing) fixes it.
And Clang is correct there, i added a second commit to the PR that should fix the problem with Out.h