开发者

Template deduction and function pointers

How does the compiler know the correct type for this code:

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

    ActionMapType actions;

    templ开发者_开发技巧ate <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"; }
}

I am aware that I am passing Derived as ControllerType but how can the compiler know for sure that Derived is the template parameter?


The template parameter is ControllerType which is used in the function parameter list as ViewType (ControllerType::*action)() parameter. When you supply an actual argument of ViewType (Derived::*)() type, the compiler immediately realizes that ControllerType = Derived. That's it. This is called template argument deduction.

In some contexts in C++ the compiler cannot deduce the template argument from the type of function argument. Such contexts are called non-deduced contexts. The language specification provides a list of non-deduced contexts. And yours is not one of them.


Function templates will deduce their types.

You have ViewType (ControllerType::*action)(), where ControllerType can be any class. So basically it's looking for a pointer to a class function that takes nothing and returns a ViewType and the class can be any class. The "any type" must be Derived.


It knows Derived is the template parameter because you specified &Derived::foo (and not, say, &SomethingElse::foo) in the addAction() function call. This is determined at compile time, so no RTTI is needed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜