Using template argument in a macro

Hi.I'm trying to generate constant strings with template arguments, and I have no idea how to do that.

Here's a simple example:
1
2
3
4
5
6
#define tostring(x) #x
template<int ID>
void printID()
{
    printf(tostring(ID));
}


And if I try to use it in my code like so:
printID<3>();

I want "3" printed, but instead I get "ID".
I think you are trying to accomplish this...

tostring(x) creates a literal out of your ID tag.

1
2
3
4
5
template<int ID>
void printID()
{
	printf("%d",ID);
}
Thank you for your reply. However, that's not quite what I'm looking for. I guess my example doesn't clearly communicate what I'm trying to do. What I really want to do is have a separate constant string for each template expansion. (I'm not even sure if it's possible)

for something like this:

1
2
3
4
5
6
#define tostring(x) #x
template<int ID>
void printID()
{
    ????? = tostring(ID); // i don't know what i need to do
}

when I compile it with printID<1> and printID<2> statements,
I want the compiler to expand the template function like such:
1
2
3
4
5
6
7
8
9
void printID_1()
{
    const char *name = "1";
}

void printID_2()
{
    const char *name = "2";
}


And they have to be constant strings. Let's just say that I can't afford sprintf.
closed account (o1vk4iN6)
I don't think what you are trying to do is possible, as far as I know it's not possible to pass a string through as a template. You'd need to make it a parameter.
I see. I figured that as long as macro expansion happens after template expansion, it'd be doable, but I suppose that's not the case?
Thank you guys for your help.
Ok I see, I believe this is possible with using macros only, not sure about the use of templates here. We had something similar for an in house library. However, every single developer scolded such implementation and has since been 're-architected'.
GooseMunch wrote:
I see. I figured that as long as macro expansion happens after template expansion, it'd be doable, but I suppose that's not the case?


No it is not - macro expansion is carried ou by the preprocessor well before anything to do with
templates.
Your problem interested me so I imagined a solution but not sure if this is what you are looking for:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
template <bool Test, typename Rtrue, typename Rfalse>
struct if_
{
	enum { value = Rtrue::value };
};

template <typename Rtrue, typename Rfalse>
struct if_<false, Rtrue, Rfalse>
{
	enum { value = Rfalse::value };
};

template <int N>
struct number
{
	enum { value = N };
};

template <int N>
struct nb_digits_r
{
	enum { value = 1 + nb_digits_r<N / 10>::value };
};

template<>
struct nb_digits_r<0>
{
	enum { value = 0 };
};

template <int N>
struct nb_digits
{
	enum { value = nb_digits_r<N>::value };
};

template<>
struct nb_digits<0>
{
	enum { value = 1 };
};

template <int N, int Digit>
struct nth_digit_r
{
	enum { value = nth_digit_r<N / 10, Digit - 1>::value };
};

template <int N>
struct nth_digit_r<N, 0>
{
	enum { value = N % 10 + '0' };
};

template <int N, int Digit>
struct nth_digit
{
	enum { value = if_<nb_digits<N>::value <= Digit, number<0>, nth_digit_r<N, nb_digits<N>::value - Digit - 1>>::value };
};

template <int ID>
struct to_str
{
	static const char value[15];
};

// work with up to 5 digits add until nth_digit<ID, N> for more
template <int ID>
const char to_str<ID>::value[15] = {nth_digit<ID, 0>::value, nth_digit<ID, 1>::value, nth_digit<ID, 2>::value, nth_digit<ID, 3>::value, nth_digit<ID, 4>::value, 0};


With this, to_str<N>::value is a constant null-terminated string which contains the decimal representation of N (with 0 < N < 99999). Works well with some numbers I tried but if you want to make it work with number above 5 digits you need some modifications described in comments (or use boost::preprocessor to repeat macro).
Haha, that's pretty awesome. Unfortunately I decided to go with another route (simple lookup table - thankfully I know the max bound of IDs and it wasn't that big), but nevertheless thank you for the awesome solution.
Topic archived. No new replies allowed.