
On Thu, Dec 19, 2024 at 2:20 PM Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
...if there was a left-to-right solution devoid of the above problems, I would take it.
Very good point. Here is a sketch of what a non-intrusive, left-to-right solution: std::unordered_map< int, char > m; upgrade(m).try_find( 1 ).map( []( auto&& v ) { std::cout << "not empty"; return v; } ); Check it out on https://godbolt.org/z/jKzqbs3nj #include <optional> #include <boost/optional.hpp> #include <iostream> template< typename T > concept associative_map = requires( T ) { typename T::value_type; }; template< associative_map M > struct upgrade_wrapper { explicit upgrade_wrapper( M& m ) : m_(m) { } template< typename Key > auto try_find( Key&& k ) -> boost::optional< typename M::value_type& > { auto it = m_.find( std::forward< Key > ( k ) ); if( it != m_.end() ) return *it; return {}; } private: M& m_; }; template< associative_map M > auto upgrade( M& m ) -> upgrade_wrapper< M > { return upgrade_wrapper< M >(m); } int main() { std::unordered_map< int, char > m; upgrade(m).try_find( 1 ).map( []( auto&& v ) { std::cout << "not empty"; return v; } ); } Thanks