By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,505 Members | 1,761 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,505 IT Pros & Developers. It's quick & easy.

expression template, two arguments, partial specialisation error

P: n/a
Hi,

I'm trying to use expression templates to calculate values at compile time.
Doing it with just one parameter is no problem:

///Begin Listing 1
#include <iostream>
using namespace std;

template <int n> void UNROLL(){
cout << "n = " << n << endl;
UNROLL<n-1>();
}

template <> void UNROLL<0>() {
cout << "Hit Zero!" << endl;
}

int main(){
UNROLL<10>();
return 0;
}
///Begin Listing 1

However, if I want to use two parameters, I have to explicitly set both in
the abortion rule like this:

///Begin Listing 2
#include <iostream>

using namespace std;

template <int n, int m> void UNROLL(){
cout << "m*n = " << m*n << endl;
UNROLL<n, m-1>();
}

template <> void UNROLL<5, 0>() {
cout << "Hit Zero!" << endl;
}

int main(){
UNROLL<5, 10>();
return 0;
}
//End Listing 2

Of course, this is not what I want, I want the recursion to abort with
n == (any value) and m == 0. I tried to change the second program like this:

template <int n> void UNROLL<n, 0>() {
cout << "Hit Zero!" << endl;
}

But this gives me the error

temprektest_func.cpp:12: error: partial specialization `UNROLL<n, 0>' of
function template

and more errors about exceeding the maximum instantiation depth of
templates.

I tried google first. I did not find anything exactly like what I wanted,
but guessing from examples involving classes, this seemed to be the syntax
to use. Is this a limitation of my compiler (G++ 3.3.6), am I doing it
wrong or is it simply not possible to specialize expression templates in
this way?

Thanks, Martin

Nov 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Martin Gernhard wrote:
I'm trying to use expression templates to calculate values at compile time.
[...]
template <int n, int m> void UNROLL(){
cout << "m*n = " << m*n << endl;
UNROLL<n, m-1>();
}

template <> void UNROLL<5, 0>() {
cout << "Hit Zero!" << endl;
}

int main(){
UNROLL<5, 10>();
return 0;
}
//End Listing 2

Of course, this is not what I want, I want the recursion to abort with
n == (any value) and m == 0. I tried to change the second program like this:

template <int n> void UNROLL<n, 0>() {
cout << "Hit Zero!" << endl;
}

But this gives me the error

temprektest_func.cpp:12: error: partial specialization `UNROLL<n, 0>' of
function template

[...]


First of all, there are no partial specialisations of function templates.
Period. Once you admit that to yourself, you can start working towards
a solution, like making your 'UNROLL<n,m>' into a class template.

V
Nov 22 '05 #2

P: n/a
Victor Bazarov wrote:
Martin Gernhard wrote:
I'm trying to use expression templates to calculate values at compile
time.
[...]
template <int n, int m> void UNROLL(){
cout << "m*n = " << m*n << endl;
UNROLL<n, m-1>();
}

[...]
template <int n> void UNROLL<n, 0>() {
cout << "Hit Zero!" << endl;
}

But this gives me the error

temprektest_func.cpp:12: error: partial specialization `UNROLL<n, 0>' of
function template

[...]
First of all, there are no partial specialisations of function templates.
Period. Once you admit that to yourself, you can start working towards
a solution, like making your 'UNROLL<n,m>' into a class template.


Thank you very much, this was exactly the clarification I needed. Using the
last example from http://medialab.di.unipi.it/web/AP/MetaProgramming.ppt as
a rough guideline (I found it before my first posting but did not realize I
_needed_ to use classes) the program now calculates binomial coefficients.

To anyone interested, here it is. Because it is ignorant of integer
overflow, its usefulness is probably rather limited.

Thank you very much!

//Listing 1

#include <iostream>

using namespace std;

template <int k> int faculty(){
return k * faculty<k-1>();
}

template<> int faculty<0>(){
return 1;
}

// BinoCoeff - Calculates (n choose k)
template <int n, int k> class BinoCoeff{
public:
static void BinoCoeff::doIt(){
cout << "( " << n << " choose " << k << " ) = "
<< (faculty<n>()/(faculty<k>() * faculty<n-k>())) << endl;
}
};
// BinoCoeffs - Calculates all binomial coefficients
// (n choose k) with k = 0...n.
template <int n, int k, int i> class BinoCoeffs{
public:
static void next(){
BinoCoeff<n, k>::doIt();
BinoCoeffs<n, k+1, i-1>::next();
}
};

template <int n, int k> class BinoCoeffs<n, k, -1>{
public:
static void next(){
}
};
// AllBinoCoeffs - Calculates all binomial coefficients
// of all numbers from n to i.
template <int n, int i> class AllBinoCoeffs{
public:
static void next(){
BinoCoeffs<n, 0, n>::next();
AllBinoCoeffs<n+1, i-1>::next();
}
};

template <int n> class AllBinoCoeffs<n, -1>{
public:
static void next(){
}
};
typedef AllBinoCoeffs<0, 12> BinoCoeffs_0_to_12;

int main(){
BinoCoeffs_0_to_12 *binos = new BinoCoeffs_0_to_12;
binos->next();
delete binos;
}

Nov 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.