简体   繁体   中英

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;

    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"; }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM