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!).
See Question&Answers more detail:os