显式函数模板特化选择错误的特化

时间:2016-04-05 15:15:49

标签: c++ templates template-specialization

我在一个类中有2个函数,一个是operator + =的默认specilized,它需要某种函数,而第二个specilization需要一个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 ) 
                        {
                            [...]
                        } );

谢谢!

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

要正确专业化,只需使用

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

即,从模板特化中删除引用。以下是这种专业化应该如何工作的示例 - 使用熟化类型,但应该有用:

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

(取决于您的编译器,您可能需要在专业化中在'&gt;&gt;'之间加一个空格)。