Как вывести тип класса из типа метода в шаблонах C ++?

В шаблонах, как показано ниже, я хотел бы позвонитьRun(&Base::foo) успешно без необходимости называть базовый тип дважды (как это делается при компиляцииRun<Base>(&Base::foo) вызов). Могу ли я иметь это? Возможно без добавления тонныУвеличение заголовки?

С предоставленным кодом я получаю ошибку:

prog.cpp:26: error: no matching function for call to ‘Run(bool (Base::*)())’

(Вы можете возиться с фрагментом вhttp://ideone.com/8NZkq):

#include <iostream>

class Base {
public:
  bool foo() { return true; }
};

Base* x;

template<typename T>
struct Traits {
  typedef bool (T::*BoolMethodPtr)();
};

template<typename T>
void Run(typename Traits<T>::BoolMethodPtr check) {
  T* y = dynamic_cast<T*>(x);
  std::cout << (y->*check)();
}

int main() {
  Base y;
  x = &y;
  Run<Base>(&Base::foo);
  Run(&Base::foo); // why error?
}
 Potatoswatter30 сент. 2010 г., 14:59
@ian: но мы делаем!
 John Dibling30 сент. 2010 г., 14:46
Что с трудными вопросами о ТАК этим утром? Обычно это «как вы форматируете шестнадцатеричное число» или «что такое метод const». Сегодня утром я действительно должен подумать. :)
 ianmac4530 сент. 2010 г., 14:37
вы знаете, компиляторы не работают автоматически, как вы хотите их ...

Ответы на вопрос(1)

Решение Вопроса

T вTraits<T>::BoolMethodPtr находится в не выводимом контексте, поэтому компилятор не будет автоматически выводить из вызова тип T. Это потому, что может быть такой код:

struct Traits {
  typedef bool (T::*BoolMethodPtr)();
};

template<>
struct Traits<int> {
  typedef bool (Base::*BoolMethodPtr)();
};

Run(&Base::foo); /* What should T be deduced to? Base and int are both equally possible */

Если вы можете обойтись безTraits<T> класс, вы можете написатьRun как:

template<class Class>
void Run(bool (Class::*check)()) {
  Class* y = dynamic_cast<Class*>(x);
  std::cout << (y->*check)();
}

В данном контексте,Class может быть выведено, чтобы означатьBase

 Potatoswatter30 сент. 2010 г., 15:04
d'ах! Твой ответ лучше моего.
 akavel30 сент. 2010 г., 15:26
Конечно, я могу обойтись без! Аааа, ты говоришь, что это выполнимо, а я слишком усложнил; LOL, жизнь смешная :) Большое спасибо за решение; Что касается объяснения, похоже, мне придется подойти к нему как-нибудь в другой день, после хорошего ночного сна;) спасибо всем в этой ветке, вы получите свои +1, все ответы очень интересные, каждый приносит часть головоломки

Ваш ответ на вопрос