Re[5]: bind2nd
От: Павел Кузнецов  
Дата: 28.03.02 16:28
Оценка:
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>:
  1. исправить объявление (как верно заметил Bell)
    class mem_fun1_ref_t : public binary_function<_Ty * , _A, _R> на
    class mem_fun1_ref_t : public binary_function<_Ty, _A, _R>

  2. добавить реализацию адаптеров для константных функций-членов перед строкой _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)); }
что подтверждается полевыми испытаниями
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.