https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521
Matthijs van Duin <matthijsvanduin at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |matthijsvanduin at gmail dot com --- Comment #3 from Matthijs van Duin <matthijsvanduin at gmail dot com> --- First off, your example is more complicated than it needs to be. A more minimal test case would be: #include <utility> struct Dest { Dest() = default; Dest( Dest && ) = default; Dest( Dest const & ) = delete; }; struct Source { Dest val; operator Dest () && { return std::move( val ); } operator Dest const & () const & { return val; } }; int main() { Source x; static_cast<Dest>( std::move( x ) ); } Second, notice that the two conversions are not really directly comparable since one converts to directly Dest while the other converts to an expression used to invoke a constructor of Dest. While it seems desirable for the former to take preference over the latter, I'm not enough of a language lawyer to be able to figure out what the C++ standard actually requires overload resolution to do in this situation. Replacing operator Dest () && { by operator Dest && () && { fixes the problem, and has the additional benefit of avoiding unnecessary temporary materialization in situations like: void foo( Dest && ); int main() { Source x; foo( std::move( x ) ); }