How to specialize variadic template function that has const reference for an argument?
Example:
template<typename T, typename... Args>
T foo(Args... args) = delete;
template<> int foo(int a, const char* str, const Test& t) { .... } // Fails to compile
//template<> int foo(int a, const char* str, Test ) { .... } // Ok
int main() {
auto i = foo<int>(10, "test string!", t);
return 0;
}
When invoking function foo with declared const Test&
argument, the compiler fails to see specialized function and fallbacks to deleted function:
error: use of deleted function ‘T foo(Args ...) [with T = int; Args = {int, const char*, Test}]’
auto i = foo<int>(10, "test string!", t);
The above code compiles fine if I remove const reference from argument. What am I doing wrong?
The code can be found here
This is because the template arguments which the primary template deduce for your call are int
, const char*
, and Test
, not const Test&
. This means that your specialization is not used because the template arguments don't match the parameters.
Your simplest option is to provide a separate overload rather than a specialization:
template <typename T>
T foo(int a, const char* str, const Test& t) { /*...*/; }
Live demo
Automatic template deduction is not smart enough to guess that you want it to set the last template parameter to const Test&
instead of Test
. More exactly type deduction always remove cv qualifiers from a type.
You new explicit template instantiation here:
auto i = foo<int, int, const char *, const Test&>(10, "test string!", t);
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