显式函数模板专门化选择了错误的专门化



我在一个类中有两个函数,一个是运算符+=的默认指定,它需要某种类型的函数,而第二个指定需要EventHandler,下面是实现:

    template<typename _Func>
    timed_function<_Sig>& operator+=( _Func &&f )
    {
        // Create an unamed handler
        auto handler = new EventHandler<_Sig>( "unamed", std::forward<_Func>( f ) );
        // Push it
        _fs.push_back( handler );
        // Return a reference to the function
        return handler->get( );
    }

这是专门的版本:

template<>
timed_function<_Sig>& operator+=<const EventHandler<_Sig>&>( const EventHandler<_Sig> &_Handler )
{
    // Copy the handler and push it
    _fs.push_back( new EventHandler<_Sig>( _Handler ) );
    // Return a reference to the function
    return _fs.back( )->get( );
}

其中_fs只是EventHandler<_Sig>指针的向量。并且_Sig是函数签名(例如void(int)

例如,当在lambda函数上使用+=运算符时,它工作得很好,编译器会选择正确的专业化:

window->OnKeyDown( ) += []( dx::Window *sender, dx::KeyDownArgs &args )
{
    [...]
};

OnKeyDown( )返回对Event<void(dx::Window*, dx::KeyDownArgs&)> 实例的引用

然而,当我尝试手动添加这样的EventHandler时,它仍然会选择该函数的非专用版本。

window->OnKeyDown( ) += EventHandler<void(dx::Window*, dx::KeyDownArgs&)>( "Key Handler", 
                        []( dx::Window *sender, dx::KeyDownArgs &args ) 
                        {
                            [...]
                        } );

谢谢!

您提供的是EventHandler<_Sig>&&而不是const EventHandler<_Sig>&,因此选择了非专用版本。

要正确地进行专门化,只需使用

template<>
timed_function<_Sig>& operator+=<const EventHandler<_Sig>>...

也就是说,从模板专门化中删除引用。以下是一个例子,说明了这种专业化应该如何工作——对于煮熟的类型,但应该是有用的:

http://coliru.stacked-crooked.com/a/297df51929329484

(根据编译器的不同,在特殊化中可能需要在">>"之间留一个空格)。

最新更新