Is it possible to override a variadic template by changing the number of fixed parameters before the function parameter pack? For example:
#include <iostream>
template <typename ...Args>
void foo(std::string, std::string, std::string, Args...)
{
std::cout << "THREE STRINGS\n";
}
template <typename ...Args>
void foo(std::string, std::string, Args...)
{
std::cout << "TWO STRINGS\n";
}
int main() {
foo("key", "msg", "data", 1);
}
Running this causes the second foo
to be called, but I want the first to be called. Is there a better way to overload this function?
Second variant is selected because it does not involve an extra conversion required to create an instance of std::string
for the last argument. If you call class constructors explicitly (or adjust arguments to take exactly what you pass) then it will work fine:
foo(std::string{"key"}, std::string{"msg"}, std::string{"data"}, 1, 2); // THREE STRINGS
online compiler
This is because a string literal is not of type std::string
. It is of type const char[N]
. So the type of the third parameter of the function instantiated from the second function template is deduced to be const char*
, which is considered a better match than the function instantiated from the first function template.
You can change the type of the parameters from std::string
to const char*
, or use explicit conversions suggested by VTT's answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With