Шаблонный вывод и функциональные указатели - PullRequest
1 голос
/ 15 января 2010

Как компилятор знает правильный тип для этого кода:

class Base
{
protected:
    typedef View * ViewType;
    typedef boost::function<ViewType ()> ActionType;
    typedef boost::unordered_map<std::string, ActionType> ActionMapType;

    ActionMapType actions;

    template <class ControllerType>
    inline void addAction(std::string actionName, ViewType (ControllerType::*action)()) { actions.insert(ActionMapType::value_type(actionName, bind<ViewType>(&action, static_cast<ControllerType *>(this)))); }
};

class Derived : public Base
{
    Derived()
    {
        addAction("someAction", &Derived::foo); // No template
    }

    ViewType foo() { cout << "foo"; }
}

Мне известно, что я передаю Derived как ControllerType, но как компилятор может точно знать, что Derived является параметром шаблона?

Ответы [ 3 ]

2 голосов
/ 15 января 2010

Параметр шаблона - ControllerType, который используется в списке параметров функции как параметр ViewType (ControllerType::*action)(). Когда вы предоставляете фактический аргумент типа ViewType (Derived::*)(), компилятор сразу понимает, что ControllerType = Derived. Вот и все. Это называется вычетом аргументов шаблона.

В некоторых контекстах в C ++ компилятор не может вывести аргумент шаблона из типа аргумента функции. Такие контексты называются не выведенными контекстами . Спецификация языка предоставляет список невыгруженных контекстов. И ваш не один из них.

1 голос
/ 15 января 2010

Шаблоны функций будут выводить их типы.

У вас есть ViewType (ControllerType::*action)(), где ControllerType может быть любым классом. Таким образом, в основном он ищет указатель на функцию класса, которая ничего не берет и возвращает ViewType, и класс может быть любым классом. «Любой тип» должен быть Derived.

0 голосов
/ 15 января 2010

Он знает, что Derived является параметром шаблона, потому что вы указали &Derived::foo (а не, скажем, &SomethingElse::foo) в вызове функции addAction(). Это определяется во время компиляции, поэтому RTTI не требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...