Я не могу понять, что я делаю неправильно. Проблема в выводе шаблона из указателя на элемент базового класса - & DerivedClass :: BaseClassMemeber.
Полный пример:
#include <vcl.h>
#include <tchar.h>
struct Base
{
int BaseClassMember;
};
struct Derived : public Base
{
};
template<class T1, class T2>
void Test(T1& Param1, T2 T1::* Param2)
{
}
int _tmain()
{
Derived inst;
// Compile error E2285 Could not find a match for 'Test<T1,T2>(B,int A::*) - BCC32
// Error 1 error C2782: 'void Test(T1 &,T2 T1::* )' : template parameter 'T1' is ambiguous - MS VS8
Test(inst, &Derived::BaseClassMember);
// Works great
Test<Derived>(inst, &Derived::BaseClassMember);
return 0;
}
Я могу найти несколько обходных решений, например, перегрузка дополнительной функции тестирования с помощью еще одного параметра шаблона, static_cast, неявной частичной специализации (Test).
Но меня интересуют причины, по которым complier просто не может использовать класс, который явно указан в & DerivedClass :: BaseClassMemeber. Вот в чем вопрос. И если у вас есть более элегантное решение проблемы, добро пожаловать.
&Derived::BaseClassMember
имеет тип int Base::*
, а не int Derived::*
. Quot the Standard:
Результатом унарного оператора
&
является указатель на его операнд. Операнд должен быть lvalue или identified-id. Если операнд является квалифицированным идентификатором, именящим нестатический членm
некоторого классаC
с типомT
, результат имеет тип "указатель на член классаC
типаT
" и является присвоением знакаC::m
. [... skip...] [Пример:
struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*i
- конец примера]
Вы должны указать значение int Derived::*
если вам нужен этот тип.
Test<Base>
, однако, делает .