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
ControllerTypewhich is used in the function parameter list asViewType (ControllerType::*action)()parameter. When you supply an actual argument ofViewType (Derived::*)()type, the compiler immediately realizes thatControllerType = 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.