Variadic template functions

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.

So I did the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;

int foo() {
    return 0;
}

template<char digit, char... remainingDigits>
int foo() {
    return (int(digit)-int('0')) + 10 * foo<remainingDigits...>();
}

template<char... Digits>
int operator "" _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]


I am using the g++ compiler (Version 4.7.1).
I did solve the problem by passing the digits as a parameter to the foo function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;

int foo() {
	return 0;
}

int pow(int base, int exp) {
	int res = 1;
	for(int i=0;i<exp;i++)
		res *= base;
	return res;
}

template<typename T1, typename... TR>
int foo(T1 c1, TR... cr) {
	return pow(10, sizeof...(TR))*(int(c1)-int('0')) + foo(cr...);
}

template<char... Digits>
int operator "" _integer() {
	return foo(Digits...);
}

int main(int argc, char **argv) {
	int test = 197213421_integer;
	
	cout << test << endl;
	
	return 0;
}


Any hints why my first approach did not work are still welcome of course; I still have no clue why it did not work.
Last edited on
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:
1
2
3
4
template<typename = void>
int foo() {
    return 0;
}
Thanks a lot :)

That's exactly what i was searching for, problem solved.
Topic archived. No new replies allowed.