Вычисление шаблона из указателя на член базового класса

0

Я не могу понять, что я делаю неправильно. Проблема в выводе шаблона из указателя на элемент базового класса - & 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. Вот в чем вопрос. И если у вас есть более элегантное решение проблемы, добро пожаловать.

  • 0
    Вам также может быть интересно, что ваши «Отлично работает» не на clang 3.3. Test<Base> , однако, делает .
  • 0
    Хорошо, это исключает один обходной путь, но, тем не менее, где проблема?
Показать ещё 2 комментария
Теги:
templates
template-deduction
pointer-to-member

1 ответ

1
Лучший ответ

&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::* если вам нужен этот тип.

  • 0
    Спасибо за ответ, я нашел эту ссылку после вашей подсказки. Оставьте это здесь для подробной информации. open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3772.pdf

Ещё вопросы

Сообщество Overcoder
Наверх
Меню