views:

389

answers:

5

Is it possible to write a template

Foo<int n>

such that:

Foo<2>

gives

switch(x) {
  case 1: return 1; break;
  case 2: return 4; break;
}

while

Foo<3>

gives

switch(x) {
  case 1: return 1; break;
  case 2: return 4; break;
  case 3: return 9; break;
}

?

Thanks!

EDIT:

changed code above to return square, as many have guessed (and I poorly asked)

A: 

No, you will need a lookup table for something like that mate.

acron
A: 

I don't believe you are actually looking for templates here, but rather macros. Try this reference for info on the C preprocessor, which may be able to do what you want. Templates work on types, and aren't suited to what you are trying to do.

avpx
I'm not a C++ expert, but I believe templates can work on values. That's why the `typename` keyword exists: to create templates that work on types.
Martinho Fernandes
Indeed, for example to compute a square at compile-time `template <int N> struct square { static const int value = N * N; }`. They don't generate normal switches, although it might be possible to set up a compile-time switch with template meta-programming (loops and if's are doable, so I don't see why a switch shouldn't be) - but it is hard to see what the OP wants to achieve in the first place.
UncleBens
+1  A: 

You won't be able to use template metaprogramming to evaluate the result of the switch if the value you're switching on (in this case, x) is not known at compile time. This is because templates are blown-out at compile-time, not at run time.

However, if you know the value at compile-time, you can achieve a similar effect:

#include <cstdlib>
#include <iostream>
using namespace std;

template<int V> struct intswitch
{
    operator int() const
    {
        return V * V;
    }
};

int main() {

    cout << "1 = " << intswitch<1>() << endl
        << "2 = " << intswitch<2>() << endl
        << "3 = " << intswitch<3>() << endl
        << "4 = " << intswitch<4>() << endl
        << "5 = " << intswitch<5>() << endl
        << "6 = " << intswitch<6>() << endl
        << "7 = " << intswitch<7>() << endl
        << "8 = " << intswitch<8>() << endl
        << "9 = " << intswitch<9>() << endl
        << "10 = " << intswitch<10>() << endl
        ;
}

Program output:

1 = 1
2 = 4
3 = 9
4 = 16
5 = 25
6 = 36
7 = 49
8 = 64
9 = 81
10 = 100
John Dibling
+1  A: 

Sort-a, kind-a, not really. You can get something close to the behavior you are asking for although not done with an actual switch.

Okay, I'm assuming foo<N> means the ability to calculate the square of any value between 1 and N but no other values. So, I came up with this:

template <int t>
int foo(int x)
{
    return (x > t)   ? -1 :
           (x == t)  ? (x * x) :
                       foo<t -1>(x);
}    

template <>
int foo<0>(int x)
{
    return -1;
}
R Samuel Klatchko
The runtime complexity is... bad. Why using another template if `x < t` ? In the end, as long as `x` is in `[0,t]` you'll get `x*x` as a result, no need to go recursive there.
Matthieu M.
+3  A: 

Yes, make a template with an oversized master switch and hope/help the optimizer turns it into a little switch. See my answer to your other question http://stackoverflow.com/questions/2157149/runtime-typeswitch-for-typelists-as-a-switch-instead-of-a-nested-ifs. Also, don't duplicate-post.

Potatoswatter