简体   繁体   English

显式功能模板专业化选择错误的专业化

[英]Explicit function template specialization picks the wrong specialization

I have 2 functions inside a class, one is the default specilization of the operator+= which expects a function of some sort, whilst the second specilization expects an EventHandler, here is the implementation: 我在一个类中有2个函数,一个是operator + =的默认规范,它期望某种功能,而第二个规范期望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( );
    }

Here's the specialized version: 这是专业版本:

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( );
}

Where _fs is just a vector of EventHandler<_Sig> Pointers. 其中_fs只是EventHandler<_Sig>指针的向量。 And _Sig being the function signature (eg void(int) ) _Sig是函数签名(例如void(int)

When using the += operator on for example a lambda function it works just fine and the compiler picks the correct specialization: 例如,在lambda函数上使用+ =运算符时,它可以正常工作,并且编译器会选择正确的专业化:

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

OnKeyDown( ) returns a reference to an instance of Event<void(dx::Window*, dx::KeyDownArgs&)> OnKeyDown( )返回对Event<void(dx::Window*, dx::KeyDownArgs&)>实例的引用。

However when I try and manually add an EventHandler like this it still picks the non-specialized version of the function. 但是,当我尝试手动添加这样的EventHandler时,它仍然会选择该函数的非专业版本。

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

Thanks! 谢谢!

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

To properly specialize, just use 要正确专业化,只需使用

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

That is, remove the reference from template specialization. 即,从模板专门化中删除引用。 Here is an example of how this sort of specialization should work - with cooked-up types, but should be useful: 这是这种专业化应如何工作的示例-熟化类型,但应有用:

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

(depending on your compiler, you might have to put a space between '>>' in specialization). (根据您的编译器,您可能必须在专业化中的“ >>”之间放置一个空格)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM