Re: О шаблонах и специализациях
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.06.02 14:19
Оценка: 9 (1)
Здравствуйте achp, Вы писали:

Ты напоролся сразу на две ошибке в компиляторе VC6.
1. VC6 не поддерживает тип void в полной мере
2. VC6 не поддерживает частичную специализацию шаблонов.
Re[4]: О шаблонах и специализациях
От: Павел Кузнецов  
Дата: 29.06.02 05:21
Оценка: 9 (1)
Здравствуйте DarkGray, Вы писали:

(...)

DG>template< class Delegate, class Arg, class Result >
DG>class closure_t : public _closure_t<Delegate, Arg, _closure_base<Deletegate, Arg, Result> >::template TT<Result>
DG>{
DG>};


В данном случае необходимо добавлять ключевое слово template, как указано в коде.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
О шаблонах и специализациях
От: achp  
Дата: 27.06.02 14:11
Оценка: 5 (1)
Маленький и очень скромный шаблон:

template< class Delegate, class Arg, class Result >
class closure_t :
    public std::unary_function< Arg, Result >
{
private:
    Delegate& _d;
    Result (Delegate::*_f)(Arg);

public:
    explicit closure_t(Delegate& d, Result (Delegate::*f)(Arg)) :
        _d(d), _f(f)
    {}

    Result operator()(Arg x) const
    { 
        return (_d.*_f)(x);
    }
};


... со вспомогательной функцией:

template< class Delegate, class Arg, class Result >
closure_t< Delegate, Arg, Result > closure(Delegate& d, Result (Delegate::*f)(Arg))
{
    return closure_t< Delegate, Arg, Result >(d, f);
}


При попытке использования при Result = void, компилятор (MSVC++ 6.0) ругается на return в closure_t::operator()().

В связи с этим, Вопрос 1: Он правильно ругается? Ведь (_d._f)(x) имеет тип void, и, как мне раньше казалось, такая конструкция допустима. И как тогда работают std::mem_fun_t и прочие, если тип адаптируемой функции void?

Далее, пытаясь обойти сие, тщусь написать специализацию:

template< class Delegate, class Arg >
class closure_t< Delegate, Arg, void > :
    public std::unary_function< Arg, void >
{
private:
    Delegate& _d;
    void (Delegate::*_f)(Arg);

public:
    explicit closure_t(Delegate& d, void (Delegate::*f)(Arg)) :
        _d(d), _f(f)
    {}

    void operator()(Arg x) const
    { 
        (_d.*_f)(x);
    }
};


Компилятор мне на это отвечает:

error C2989: 'closure_t<Delegate,Arg,void>' : template class has already been defined as a non-template class
error C2988: unrecognizable template declaration/definition



Вопрос 2: Что не так в этой специализации?

PS: К сожалению, образцов типа boost под рукою нет.
Re[2]: О шаблонах и специализациях
От: achp  
Дата: 27.06.02 14:34
Оценка:
DG>Ты напоролся сразу на две ошибке в компиляторе VC6.
DG>1. VC6 не поддерживает тип void в полной мере
DG>2. VC6 не поддерживает частичную специализацию шаблонов.

Спасибо на добром слове.

Так что же делать?
Re[3]: О шаблонах и специализациях
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.06.02 14:42
Оценка:
Здравствуйте achp, Вы писали:

DG>>Ты напоролся сразу на две ошибке в компиляторе VC6.

DG>>1. VC6 не поддерживает тип void в полной мере
DG>>2. VC6 не поддерживает частичную специализацию шаблонов.

A>Спасибо на добром слове.


A>Так что же делать?


Пишется, что-то такое:


template< class Delegate, class Arg, class Result>
class _closure_base:
    public std::unary_function< Arg, Result >
{
private:
    Delegate& _d;
    Result (Delegate::*_f)(Arg);

public:
    explicit closure_t(Delegate& d, Result (Delegate::*f)(Arg)) :
        _d(d), _f(f)
    {}
};


template< class Delegate, class Arg, class Base>
class _closure_t:
  public Base
{
public:
   template<class Result>
   class TT
   {
    Result operator()(Arg x) const
    { 
        (_d.*_f)(x);
    }
   }
   template<>
   class TT<void>
   {
    void operator()(Arg x) const
    { 
       (_d.*_f)(x);
    }
   }
};

template< class Delegate, class Arg, class Result >
class closure_t : public _closure_t<Delegate, Arg, _closure_base<Deletegate, Arg, Result> >::TT<Result>
{
};
Re[4]: О шаблонах и специализациях
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.06.02 14:44
Оценка:
Здравствуйте DarkGray, Вы писали:

Вернее, так:
template< class Delegate, class Arg, class Base>
class _closure_t
{
public:
   template<class Result>
   class TT:
      public Base
   {
    Result operator()(Arg x) const
    { 
        (_d.*_f)(x);
    }
   }
   template<>
   class TT<void>
   {
    void operator()(Arg x) const
    { 
       (_d.*_f)(x);
    }
   }
};
Re[3]: О шаблонах и специализациях
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 27.06.02 15:21
Оценка:
Здравствуйте achp, Вы писали:

DG>>Ты напоролся сразу на две ошибке в компиляторе VC6.

DG>>1. VC6 не поддерживает тип void в полной мере
DG>>2. VC6 не поддерживает частичную специализацию шаблонов.

A>Спасибо на добром слове.


A>Так что же делать?


Так же применяется такая техника:


template<class T, class Arg, class Result>
struct Injection
{
  template<class TResult>
  struct TT0
  {
    Result operator()(Arg x) const
    { 
      const T * t = static_cast<const T*>(this);
        return (t->_d.*t->_f)(x);
    }
  };
  template<>
  struct TT0<void>
  {
    Result operator()(Arg x) const
    { 
      const T * t = static_cast<const T*>(this);
      (t->_d.*t->_f)(x);
    }
  };
  typedef TT0<Result> TT;
};

template< class Delegate, class Arg, class Result >
class closure_t :
    public std::unary_function< Arg, Result >,
    public Injection<closure_t, Arg, Result>::TT
{
friend Injection<closure_t, Arg, Result>::TT;
private:
    Delegate& _d;
    Result (Delegate::*_f)(Arg);

public:
    explicit closure_t(Delegate& d, Result (Delegate::*f)(Arg)) :
        _d(d), _f(f)
    {}

};
Re[3]: О шаблонах и специализациях
От: m.a.g. Мальта http://dottedmag.net/
Дата: 28.06.02 03:59
Оценка:
Здравствуйте achp, Вы писали:

DG>>Ты напоролся сразу на две ошибке в компиляторе VC6.

DG>>1. VC6 не поддерживает тип void в полной мере
DG>>2. VC6 не поддерживает частичную специализацию шаблонов.

A>Спасибо на добром слове.


A>Так что же делать?


У меня была похожая проблема, вот результат: Адаптер обобщенного указателя на функцию-член класса
Автор(ы): Михаил Гусаров aka MAG
Рассуждения на тему обобщения некоторых конструкций STL и неполной совместимости компиляторов со стандартом C++
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.