模板推导和函数指针

时间:2010-01-15 01:59:35

标签: c++ templates function-pointers

编译器如何知道此代码的正确类型:

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 个答案:

答案 0 :(得分:2)

模板参数为ControllerType,在函数参数列表中用作ViewType (ControllerType::*action)()参数。当您提供ViewType (Derived::*)()类型的实际参数时,编译器会立即意识到ControllerType = Derived。而已。这称为模板参数推导。

在C ++的某些上下文中,编译器无法从函数参数的类型推导出模板参数。这种上下文称为非推导的上下文。语言规范提供了非推断的上下文列表。而你的不是其中之一。

答案 1 :(得分:1)

功能模板将推断出它们的类型。

您有ViewType (ControllerType::*action)(),其中ControllerType可以是任何类。所以基本上它正在寻找一个指向类函数的指针,该函数不需要任何东西并返回ViewType,并且该类可以是任何类。 “任何类型”必须为Derived

答案 2 :(得分:0)

它知道Derived是模板参数,因为您在&Derived::foo函数调用中指定了&SomethingElse::foo(而不是addAction())。这是在编译时确定的,因此不需要RTTI。