Hi,
In Item 35 of "Effective STL", Scott Meyers says to "Implement simple case-insensitive string comparisons via mismatch or lexicographical_compare".
I can see how the mismatch version would work, but when I tried creating a string comparison function with lexicographical_compare(), it isn't working because lexicographical_compare() only returns true "if the range of elements [start1,end1) is lexicographically less than the range of elements [start2,end2)".
I tried adding a not2() around the predicate, but that didn't help.
I have almost the same code as the book (except I'm using the C++ tolower() function)...
Am I doing something wrong, or did I completely misunderstand what Scott was talking about?Code:/** ToLowerChar * This is a functor that wraps the std::tolower() function. */ template <typename E> class ToLowerChar : public std::binary_function<E, std::locale, E> { public: /** ToLowerChar() * A constructor for the ToLowerChar functor that sets the Locale to use when converting * the characters to lower-case. * * @param loc [IN] - The locale to use for character conversions. */ ToLowerChar( const std::locale& loc = std::locale() ) : m_Locale( loc ) {} /** operator() * This operator will return a lower-case version of the character passed to it. * * @param ch [IN] - This is the character to convert to lower-case. * * @param loc [IN] - (optional) This is the locale to use. * * @return E - The lower-case version of the character that was passed in. */ E operator()( E ch ) const { return std::tolower( ch, m_Locale ); } private: const std::locale& m_Locale; /**< This is the locale to use for character conversions. */ }; /** CharLessNoCase * A functor to compare 2 characters without regard to case. */ template <typename E> class CharLessNoCase : public std::binary_function<E, E, bool> { public: /** CharLessNoCase() * A constructor for the CharLessNoCase functor that sets the Locale to use when converting * the characters to lower-case. * * @param loc [IN] - The locale to use for character conversions. */ CharLessNoCase( const std::locale& loc = std::locale() ) : m_Locale( loc ) {} /** operator() * First converts both characters to lower-case, then returns true if they * are the same or false if they're not. * * @param c1 [IN] - The first character to compare. * * @param c2 [IN] - The second character to compare. * * @return bool - true if the characters are the same (ignoring case), * otherwise false if they're different. */ bool operator()( E c1, E c2 ) const { return (ToLowerChar<E>( m_Locale )( c1 ) < ToLowerChar<E>( m_Locale )( c2 )); } private: const std::locale& m_Locale; /**< This is the locale to use for character conversions. */ }; /** StringCompareNoCase * This functor compares 2 STL strings without regard to case. */ template <typename E, typename T = std::char_traits<E>, typename A = std::allocator<E> > class StringCompareNoCase : public std::binary_function<const std::basic_string<E, T, A>&, const std::basic_string<E, T, A>&, bool> { public: /** StringCompareNoCase() * A constructor for the StringCompareNoCase functor that sets the Locale to use when converting * the characters to lower-case. * * @param loc [IN] - The locale to use for character conversions. */ StringCompareNoCase( const std::locale& loc = std::locale() ) : m_Locale( loc ) {} /** operator() * Compares 2 STL strings without regard to case. * * @param str1 [IN] - The first string to compare. * * @param str2 [IN] - The second string to compare. * * @return bool - true if the strings are the same (ignoring case), * otherwise false if they're different. */ bool operator()( const std::basic_string<E, T, A>& str1, const std::basic_string<E, T, A>& str2 ) const { return std::lexicographical_compare( str1.begin(), str1.end(), str2.begin(), str2.end(), CharLessNoCase<E>( m_Locale ) ); } private: const std::locale& m_Locale; /**< This is the locale to use for character conversions. */ };



LinkBack URL
About LinkBacks



CornedBee
