Есть вектор строчек и специализация std::equal_to<> для этих строчек.
template<>
struct std::equal_to<const wchar_t*const> :
binary_function<const wchar_t*const, const wchar_t*const, bool>
{
bool operator()(const wchar_t*const s1, const wchar_t*const s2) const
{ return 0 == _wcsicmp(s1, s2); }
};
Лучше бы тут иметь свой предикат, но у нас так исторически сложилось
Далее std::equal_to<> специализируется для типа const wchar_t*. Есть два варианта специализации:
template<>
struct std::equal_to<const wchar_t*> : // (1)
std::equal_to<const wchar_t*const>
{
};
и
template<>
struct std::equal_to<const wchar_t*> : // (2)
binary_function<const wchar_t*, const wchar_t*, bool>
{
bool operator()(const wchar_t* s1, const wchar_t* s2) const
{ return 0 == _wcsicmp(s1, s2); }
};
Вопрос в том, почему при специализации (1) происходит ошибка компиляции?
Второй вариант компилируется без ошибок.
Вот код, вызывающий ошибку:
const wchar_t* sz = 0;
std::vector<const wchar_t*> v;
std::find_if(v.begin(), v.end(),
std::bind1st(std::equal_to<const wchar_t*>(), sz)); // line 890
А вот и сама ошибка(VS2005SP1) :
d:\program files\microsoft visual studio 8\vc\include\functional(282) : error C2535: 'bool std::binder1st<_Fn2>::operator ()(const wchar_t *const &) const' : member function already defined or declared
with
[
_Fn2=std::equal_to<const wchar_t*>
]
d:\program files\microsoft visual studio 8\vc\include\functional(276) : see declaration of 'std::binder1st<_Fn2>::operator ()'
with
[
_Fn2=std::equal_to<const wchar_t*>
]
d:\myprojects\test2005\test2005\test2005.cpp(890) : see reference to class template instantiation 'std::binder1st<_Fn2>' being compiled
with
[
_Fn2=std::equal_to<const wchar_t*>
]
где
template<class _Fn2>
class binder1st
: public unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type>
{ // functor adapter _Func(stored, right)
public:
typedef unary_function<typename _Fn2::second_argument_type,
typename _Fn2::result_type> _Base;
typedef typename _Base::argument_type argument_type;
typedef typename _Base::result_type result_type;
binder1st(const _Fn2& _Func,
const typename _Fn2::first_argument_type& _Left)
: op(_Func), value(_Left)
{ // construct from functor and left operand
}
result_type operator()(const argument_type& _Right) const // line 276
{ // apply functor to operands
return (op(value, _Right));
}
result_type operator()(argument_type& _Right) const
{ // apply functor to operands // line 282
return (op(value, _Right));
}
protected:
_Fn2 op; // the functor to apply
typename _Fn2::first_argument_type value; // the left operand
};