B>Но все равно проблема стандартного STL
Не стандартного, а старого Dinkumware
B> не в отсутствии дополнительного "константного" шаблона, а в определении mem_fun1_ref_t:
B>template<class _R, class _Ty, class _A>
B>class mem_fun1_ref_t : public binary_function<_Ty * , _A, _R>
И в этом
тоже.
B>Что касается приведенных Вами определений mem_fun1_ref и const_mem_fun1_ref — то здесь все нормально, но строка
B>for_each(v.begin(),v.end(),bind2nd(mem_fun1_ref( A::Func1 ),10) );
B>все равно не будет компилиться, если A::Func1 не объявлена с модификатором const.
Более того, так как в MSVC++6.0 отсутствуют версии адаптеров для константных функций-членов, при вызове функции mem_fun1_ref(&A::Func1) компилятор выдаст ошибку о том, что не может преобразовать 'int(A::*)(int)
const' к типу 'int(A::*)(int)'. На это я и указал в своем первом сообщении (может, чуть более кратко, нежели следовало)
B>Или есть биндер, у которого operator() объявлен так:
B>binder2nd::operator()(typename _Operation::first_argument_type& __x) const
Может и есть, но он не входит в стандартную библиотеку C++ и, в любом случае, в нем нет никакой необходимости, т.к. при конкретизации binder2nd<const_mem_fun1_ref_t<R, T, A> >, _Operation::first_argument_type ==
const T.
Резюме: для того, чтобы приведенный фрагмент кода компилировался MSVC++6.0 на "родной" STL, надо внести (как минимум) два изменения в заголовок <functional>:
исправить объявление (как верно заметил Bell)
class mem_fun1_ref_t : public binary_function<_Ty * , _A, _R> на
class mem_fun1_ref_t : public binary_function<_Ty, _A, _R>
добавить реализацию адаптеров для константных функций-членов перед строкой _STD_END
// TEMPLATE CLASS const_mem_fun_t
template<class _R, class _Ty>
class const_mem_fun_t : public unary_function<const _Ty *, _R> {
public:
explicit const_mem_fun_t(_R (_Ty::*_Pm)() const)
: _Ptr(_Pm) {}
_R operator()(const _Ty *_P) const
{return ((_P->*_Ptr)()); }
private:
_R (_Ty::*_Ptr)() const;
};
// TEMPLATE FUNCTION mem_fun
template<class _R, class _Ty> inline
const_mem_fun_t<_R, _Ty> mem_fun(_R (_Ty::*_Pm)() const)
{return (const_mem_fun_t<_R, _Ty>(_Pm)); }
// TEMPLATE CLASS const_mem_fun1_t
template<class _R, class _Ty, class _A>
class const_mem_fun1_t : public binary_function<const _Ty *, _A, _R> {
public:
explicit const_mem_fun1_t(_R (_Ty::*_Pm)(_A) const)
: _Ptr(_Pm) {}
_R operator()(const _Ty *_P, _A _Arg) const
{return ((_P->*_Ptr)(_Arg)); }
private:
_R (_Ty::*_Ptr)(_A) const;
};
// TEMPLATE FUNCTION mem_fun1
template<class _R, class _Ty, class _A> inline
const_mem_fun1_t<_R, _Ty, _A> mem_fun1(_R (_Ty::*_Pm)(_A) const)
{return (const_mem_fun1_t<_R, _Ty, _A>(_Pm)); }
// TEMPLATE CLASS const_mem_fun_ref_t
template<class _R, class _Ty>
class const_mem_fun_ref_t : public unary_function<const _Ty, _R> {
public:
explicit const_mem_fun_ref_t(_R (_Ty::*_Pm)() const)
: _Ptr(_Pm) {}
_R operator()(const _Ty& _X) const
{return ((_X.*_Ptr)()); }
private:
_R (_Ty::*_Ptr)() const;
};
// TEMPLATE FUNCTION mem_fun_ref
template<class _R, class _Ty> inline
const_mem_fun_ref_t<_R, _Ty> mem_fun_ref(_R (_Ty::*_Pm)() const)
{return (const_mem_fun_ref_t<_R, _Ty>(_Pm)); }
// TEMPLATE CLASS const_mem_fun1_ref_t
template<class _R, class _Ty, class _A>
class const_mem_fun1_ref_t : public binary_function<const _Ty, _A, _R> {
public:
explicit const_mem_fun1_ref_t(_R (_Ty::*_Pm)(_A) const)
: _Ptr(_Pm) {}
_R operator()(const _Ty& _X, _A _Arg) const
{return ((_X.*_Ptr)(_Arg)); }
private:
_R (_Ty::*_Ptr)(_A) const;
};
// TEMPLATE FUNCTION mem_fun1_ref
template<class _R, class _Ty, class _A> inline
const_mem_fun1_ref_t<_R, _Ty, _A> mem_fun1_ref(_R (_Ty::*_Pm)(_A) const)
{return (const_mem_fun1_ref_t<_R, _Ty, _A>(_Pm)); }
что подтверждается полевыми испытаниями
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен