C++ 0x:std :: function :: target和template参数出错

Pue*_*tis 4 c++ templates function target c++11

我目前在C++ 0x中编写事件处理程序系统.通过传递可以存储在std::function对象中的任何类型的函数/方法来注册每个事件的"处理程序"(可以有多个处理程序).这是使用重载的+ =运算符以C#样式完成的.我的事件类看起来基本上像这样(剥离以获得更好的可读性):

template<typename THandlerReturn, typename THandlerArgs...>
class Event {
    public:
        typedef THandlerReturn(HandlerSignature)(THandlerArgs...);
        typedef THandlerReturn(*HandlerFuntionPtr)(THandlerArgs...);
        typedef typename std::function<HandlerSignature> HandlerFunction;

        void operator += (HandlerFunction handler) {
            _handlers.push_back(handler);
        }

        // Some other methods for calling all handlers, ctors, etc.

    private:
        std::vector<HandlerFunction> _handlers;
};
Run Code Online (Sandbox Code Playgroud)

现在我有另一个内部方法从std::function存储在向量中的对象中检索实际的函数指针.它基本上试图做这样的事情:

// Preceeding: Get an iterator 'it' from the vector
HandlerFunctionPtr pt2func = it->target<HandlerSignature>();
Run Code Online (Sandbox Code Playgroud)

此时,当我在我的应用程序中使用Event类时,编译失败了.使用GCC 4.7版本我得到以上行的以下错误消息:

error: expected primary-expression before '>' token
error: expected primary-expression before ')' token
Run Code Online (Sandbox Code Playgroud)

我已经使用target<>()Method 进行了一些测试,并且以下工作完美,假设返回类型是void并且有一个类型的参数int:

typedef void(Signature)(int);
typedef void(*FunctionPtr)(int);
std::function<Signature> func;
FunctionPtr pt2func = func.target<Signature>();
Run Code Online (Sandbox Code Playgroud)

但是只要涉及一个模板参数,我就会得到上面发布的错误:

typedef THandlerReturn(Signature)(int);
typedef THandlerReturn(*FunctionPtr)(void);
std::function<Signature> func;
FunctionPtr pt2func = func.target<Signature>();
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我为什么它实际上是,如果是的话,是否有任何方法可以使它工作?任何帮助和见解都非常感谢!提前致谢!

Naw*_*waz 5

您需要使用template关键字:

HandlerFunctionPtr pt2func = it->template target<HandlerSignature>();
Run Code Online (Sandbox Code Playgroud)

这是因为您在类型取决于模板参数的对象上调用函数模板.如果没有关键字template,编译器将解析您的代码,

HandlerFunctionPtr pt2func = ( (it->target) < HandlerSignature ) >();
Run Code Online (Sandbox Code Playgroud)

这完全没有意义.因此错误.


要详细了解为什么template需要,请阅读@Johannes Schaub的这个优秀解释: