The Problem
Consider the following vectors:
std::vector<std::string> extensions;
extensions.push_back(".cpp");
extensions.push_back(".CPP");
extensions.push_back(".h");
extensions.push_back(".H");
std::vector<std::string> caselessUniqueExtensions;
Copy the contents of extensions into caselessUniqueExtensions, but discard all unique extensions, ignoring case. (I.e. the result should have two elements - one of either .cpp or .CPP, and one of either .h and .H.)
The Question
There are obviously many ways to do this, some more effecient than others, and some more readable than others. One such way I thought may work is the following:
#include <boost/algorithm/string/compare.hpp>
...
std::unique_copy(
extensions.begin(), extensions.end(),
caselessUniqueExts.begin(),
boost::is_iequal());
However, it fails to compile using MSVS2010:
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xlocale(626): error C2440: 'type cast' : cannot convert from 'unsigned char' to 'std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> No constructor could take the source type, or constructor overload resolution was ambiguous
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\xlocale(2211) : see reference to function template instantiation '_Elem std::_Maklocchr<_Elem>(char,_Elem *,const std::_Locinfo::_Cvtvec &)' being compiled
1> with
1> [
1> _Elem=std::basic_string<char,std::char_traits<char>,std::allocator<char>>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\xlocale(2210) : while compiling class template member function 'std::basic_string<_Elem,_Traits,_Ax> std::ctype<std::basic_string<_Elem,_Traits,_Ax>>::do_widen(char) const'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\locale(261) : see reference to class template instantiation 'std::ctype<_Elem>' being compiled
1> with
1> [
1> _Elem=std::basic_string<char,std::char_traits<char>,std::allocator<char>>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\locale(259) : see reference to function template instantiation '_Elem std::toupper<T1>(_Elem,const std::locale &)' being compiled
1> with
1> [
1> _Elem=std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> T1=std::basic_string<char,std::char_traits<char>,std::allocator<char>>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(2042) : see reference to function template instantiation 'bool boost::algorithm::is_iequal::operator ()<std::basic_string<_Elem,_Traits,_Ax>,std::basic_string<_Elem,_Traits,_Ax>>(const T1 &,const T2 &) const' being compiled
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>,
1> T1=std::basic_string<char,std::char_traits<char>,std::allocator<char>>,
1> T2=std::basic_string<char,std::char_traits<char>,std::allocator<char>>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(2070) : see reference to function template instantiation '_OutIt std::_Unique_copy<_InIt,_OutIt,_Pr>(_FwdIt,_FwdIt,_OutIt,_Pr,std::forward_iterator_tag)' being compiled
1> with
1> [
1> _OutIt=std::_Vector_iterator<std::_Vector_val<std::string,std::allocator<std::string>>>,
1> _InIt=std::basic_string<char,std::char_traits<char>,std::allocator<char>> *,
1> _Pr=boost::algorithm::is_iequal,
1> _FwdIt=std::basic_string<char,std::char_traits<char>,std::allocator<char>> *
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(2094) : see reference to function template instantiation '_OutIt std::_Unique_copy1<std::basic_string<_Elem,_Traits,_Ax>*,_OutIt,_Pr>(_InIt,_InIt,_OutIt,_Pr,std::tr1::true_type)' being compiled
1> with
1> [
1> _OutIt=std::_Vector_iterator<std::_Vector_val<std::string,std::allocator<std::string>>>,
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>,
1> _Pr=boost::algorithm::is_iequal,
1> _InIt=std::basic_string<char,std::char_traits<char>,std::allocator<char>> *
1> ]
1> c:\users\stv04463\documents\visual studio 2010\projects\pgp sandbox\pgp sandbox\main.cpp(64) : see reference to function template instantiation '_OutIt std::unique_copy<std::_Vector_iterator<_Myvec>,std::_Vector_iterator<_Myvec>,boost::algorithm::is_iequal>(_InIt,_InIt,_OutIt,_Pr)' being compiled
1> with
1> [
1> _OutIt=std::_Vector_iterator<std::_Vector_val<std::string,std::allocator<std::string>>>,
1> _Myvec=std::_Vector_val<std::string,std::allocator<std::string>>,
1> _InIt=std::_Vector_iterator<std::_Vector_val<std::string,std::allocator<std::string>>>,
1> _Pr=boost::algorithm::is_iequal
1> ]
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xlocale(593): error C2440: 'type cast' : cannot convert from 'std::basic_string<_Elem,_Traits,_Ax>' to 'unsigned char'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\xlocale(2229) : see reference to function template instantiation 'char std::_Maklocbyte<std::basic_string<_Elem,_Traits,_Ax>>(std::basic_string<_Elem,_Traits,_Ax>,const std::_Locinfo::_Cvtvec &)' being compiled
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\xlocale(2225) : while compiling class template member function 'char std::ctype<_Elem>::_Donarrow(_Elem,char) const'
1> with
1> [
1> _Elem=std::basic_string<char,std::char_traits<char>,std::allocator<char>>
1> ]
Am I missing some basic understanding here, or should it not be possible to combine std::unique_copy with boost::is_iequal?
I am aware of the alternatives - I'd like to know why I'm getting this compiler error.
std::setinstead? With one set having a case insensitive compare function?gcc 4.7.boost::is_iequal, but the documentation foris_equalsounds troubling. At least it gives me the impression that it tries to cast the arguments tounsigned charand compare for case-insensitive equality based on the locale using==.std::string. But really, it's me who is uninitiated here. It's perfectly possible that I totally got the wrong picture (plus, I didn't read the source).