перегрузка шаблона
От: pavard  
Дата: 20.09.11 10:30
Оценка:
Hello, world!

Встала задача реализовать шаблон делегата — сразу родилось:



template< typename Tret, typename Targ1 = null_t, typename Targ2 = null_t, typename Targ3 = null_t, typename Targ4 = null_t >
class delegate_t
{
   ...
            template< Tret ( * Tfunc )() > static Tret
            StrategyFunc( this_t & dgt )
                { return Tfunc(); }

            template< Tret ( * Tfunc )( Targ1 ) > static Tret
            StrategyFunc( this_t & dgt )
                { return Tfunc( dgt.m_arg1 ); }

            template< Tret ( * Tfunc )( Targ1, Targ2 ) > static Tret
            StrategyFunc( this_t & dgt )
                { return Tfunc( dgt.m_arg1, dgt.m_arg2 ); }

            template< Tret ( * Tfunc )( Targ1, Targ2, Targ3 ) > static Tret
            StrategyFunc( this_t & dgt )
                { return Tfunc( dgt.m_arg1, dgt.m_arg2, dgt.m_arg3 ); }

            template< Tret ( * Tfunc )( Targ1, Targ2, Targ3, Targ4 ) > static Tret
            StrategyFunc( this_t & dgt )
                { return Tfunc( dgt.m_arg1, dgt.m_arg2, dgt.m_arg3, dgt.m_arg4 ); }
   ...
};


использование:


typedef delegate_t< void, int > my_delegate_t;

{
  ...
  my_delegate_t dgt( & my_delegate_t::StrategyFunc< some_func > );
  ...
  dgt( 10 );
  dgt.Call();
  ...
}


под GCC все собралось и оттестировалось на ура для произвольных функций от 0 до 4 параметров.

однако под msvc( строчка 20 о которой идет речь — объявление делегата для функции без параметров ):

X:\work\libki\samples\tools\delegate.cpp(20) : error C2440: specialization: невозможно преобразовать "void (__cdecl *)(void)" в "void (__cdecl *const )(ki::null_t,ki::null_t,ki::null_t,ki::null_t)"
        Для преобразования требуется reinterpret_cast, приведение в стиле С или приведение в стиле функции
X:\work\libki\samples\tools\delegate.cpp(20) : error C2973: ki::delegate_t<Tret>::StrategyFunc: недопустимый аргумент шаблона "void (__cdecl *)(void)"
        with
        [
            Tret=void
        ]
        x:\work\libki\include\ki\tools/delegate.h(96): см. объявление "ki::delegate_t<Tret>::StrategyFunc"
        with
        [
            Tret=void
        ]
X:\work\libki\samples\tools\delegate.cpp(20) : error C2440: specialization: невозможно преобразовать "void (__cdecl *)(void)" в "void (__cdecl *const )(ki::null_t,ki::null_t,ki::null_t)"
        Для преобразования требуется reinterpret_cast, приведение в стиле С или приведение в стиле функции
X:\work\libki\samples\tools\delegate.cpp(20) : error C2973: ki::delegate_t<Tret>::StrategyFunc: недопустимый аргумент шаблона "void (__cdecl *)(void)"
        with
        [
            Tret=void
        ]
        x:\work\libki\include\ki\tools/delegate.h(93): см. объявление "ki::delegate_t<Tret>::StrategyFunc"
        with
        [
            Tret=void
        ]
X:\work\libki\samples\tools\delegate.cpp(20) : error C2440: specialization: невозможно преобразовать "void (__cdecl *)(void)" в "void (__cdecl *const )(ki::null_t,ki::null_t)"
        Для преобразования требуется reinterpret_cast, приведение в стиле С или приведение в стиле функции
X:\work\libki\samples\tools\delegate.cpp(20) : error C2973: ki::delegate_t<Tret>::StrategyFunc: недопустимый аргумент шаблона "void (__cdecl *)(void)"
        with
        [
            Tret=void
        ]
        x:\work\libki\include\ki\tools/delegate.h(90): см. объявление "ki::delegate_t<Tret>::StrategyFunc"
        with
        [
            Tret=void
        ]
X:\work\libki\samples\tools\delegate.cpp(20) : error C2440: specialization: невозможно преобразовать "void (__cdecl *)(void)" в "void (__cdecl *const )(ki::null_t)"
        Для преобразования требуется reinterpret_cast, приведение в стиле С или приведение в стиле функции
X:\work\libki\samples\tools\delegate.cpp(20) : error C2973: ki::delegate_t<Tret>::StrategyFunc: недопустимый аргумент шаблона "void (__cdecl *)(void)"
        with
        [
            Tret=void
        ]
        x:\work\libki\include\ki\tools/delegate.h(87): см. объявление "ki::delegate_t<Tret>::StrategyFunc"
        with
        [
            Tret=void
        ]
X:\work\libki\samples\tools\delegate.cpp(20) : error C2664: ki::delegate_t<Tret>::delegate_t(void (__cdecl *)(ki::delegate_t<Tret> &),const ki::ptr_t &)
: невозможно преобразовать параметр 1 из "overloaded-function" в "void (__cdecl *)(ki::delegate_t<Tret> &)"
        with
        [
            Tret=void
        ]
        Конечному типу не соответствует ни одной функции с данным именем в области видимости
NMAKE : fatal error U1077: c:\PROGRA~2\MICROS~1.0\VC\bin\cl.exe : возвращенный код "0x2"
Stop.
NMAKE : fatal error U1077: "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\nmake.exe" : возвращенный код "0x2"
Stop.
NMAKE : fatal error U1077: "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\nmake.exe" : возвращенный код "0x2"
Stop.


Помогите забороть зверя. Гуглирование не помогло.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.