Forwarding template taking precedence over overload

試著忘記壹切 提交于 2019-12-23 09:03:56

问题


I thought that a non-template would always take precedence over a template, if the arguments match up just as well.

But:

template <typename... Args>
void Trace(Args&&... args)
{
    throw "what the frak";
}

void Trace(const int&)
{}

int main()
{
    Trace(42);
}

This throws unless I make the non-template Trace(int) or Trace(int&&), i.e. not taking a const ref.

It's kind of annoying because I want to provide a different implementation for specific argument types where the real implementation of the template does not make sense (and, in fact, would not compile).

I can fix it by making the second function a specialisation, but only if I match argument types by taking an rvalue reference:

template <>
void Trace(int&&)
{}

And, well, maybe I didn't want to do that! Maybe I want to call it with a const thing sometimes and would rather not specialise twice.

Is it correct and standard-abiding that simply providing a non-template overload works this way, in this example? It's the first time I've noticed this behaviour (not that that necessarily means anything!).


回答1:


42 is an rvalue of type int, therefore it binds more closely to int&& rather than const int&. This is why it is calling your template Trace function.

If you were to call

const int i{};
Trace(i);

then your Trace(const int&) overload would be invoked.


Possible workarounds:

  • Add a Trace(int&&) overload that invokes Trace(const int&). You might also need a Trace(int&);

  • Use SFINAE on the templated Trace to prevent instantiation when the first argument is an int;

    template <typename Arg, typename... Args>
    auto Trace(Arg&& arg, Args&&... args)
        -> std::enable_if_t<!std::is_same_v<std::decay_t<Arg>, int>>
    {
        throw "what the frak";
    }   
    
  • Change the templated Trace to take const Args&... instead.



来源:https://stackoverflow.com/questions/57888165/forwarding-template-taking-precedence-over-overload

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!