I'm currently trying to understand some of the new features in c++11 and i've come across a problem with variadic templates.
What I'm trying to do is define a custom suffix for integral (and later floating point) values using variadic templates because i want the compiler to figure out the result of the calculation at compile time.
#include <iostream>
usingnamespace std;
int foo() {
return 0;
}
template<char digit, char... remainingDigits>
int foo() {
return (int(digit)-int('0')) + 10 * foo<remainingDigits...>();
}
template<char... Digits>
intoperator"" _integer() {
return foo<Digits...>();
}
int main(int argc, char **argv) {
int test = 1_integer;
cout << test;
return 0;
}
(I know this will give wrong results for numbers with more than 1 digit)
The problem is, as soon as remainingDigits is empty, i want the program to call the base function which simply returns zero. But instead of doing this, the compiler says there is no matching function to do this:
UserDefinedLiterals.cpp: In instantiation of ‘int foo() [with char digit = '1'; char ...remainingDigits = {}]’:
UserDefinedLiterals.cpp:17:24: required from ‘int operator"" _integer() [with char ...Digits = {'1'}]’
UserDefinedLiterals.cpp:22:13: required from here
UserDefinedLiterals.cpp:12:62: error: no matching function for call to ‘foo()’
UserDefinedLiterals.cpp:12:62: note: candidate is:
UserDefinedLiterals.cpp:11:5: note: template<char digit, char ...remainingDigits> int foo()
UserDefinedLiterals.cpp:11:5: note: template argument deduction/substitution failed:
UserDefinedLiterals.cpp:12:62: note: couldn't deduce template parameter ‘digit’
UserDefinedLiterals.cpp: In function ‘int foo() [with char digit = '1'; char ...remainingDigits = {}]’:
UserDefinedLiterals.cpp:13:1: warning: control reaches end of non-void function [-Wreturn-type]
For your first example, you end the recursion by calling a template function with an empty argument list, that is, foo<>();. This means that the non-template foo() is not even considered by the name lookup.
You can make it happen by making your base-case foo() a template: