views:

105

answers:

2

Say I have a macro, FOO(name), and some template class Bar<> that takes one parameter (what type of parameter is the question). Everytime I call FOO with a different name, I want to get a different instantiation of Bar. The Bar<> template doesn't actually need to be able to get at the name internally, I just need to be sure that different names create different instances of Bar<> and that using the same name (even in different translation units) always gets at the same instance of Bar<>. So here's a rough first attempt:

template<const char* x>
class Bar
{
//... stuff
};

#define FOO(name) Bar<#name>

This would work, except that char literals can't be passed as template parameters because they don't have external linkage. If there was someway in the preprocessor to get a consistent hash of 'name' to say, an int (which can then be passed to the template) that would work, but I don't see any way to do that.

Ideas?

+4  A: 

Depending on where you intend to use this macro (namespace or class scope would work), you could create a tag type and use that:

template<typename T>
class Bar
{
//... stuff
};

#define FOO(name) struct some_dummy_tag_for_##name {}; Bar<some_dummy_tag_for_##name>

If this doesn't work, maybe you can "declare" those names before-hand:

#define DECLARE_FOO(name) struct some_dummy_tag_for_##name {}
#define FOO(name) Bar<some_dummy_tag_for_##name>

// something.h
DECLARE_FOO(foobar);

// something.cpp
FOO(foobar);
sbi
surely you mean `template<typename T>`?
bdonlan
@bdonlan: Um, yeah, I just copied the code without really thinking. Sorry. Will fix.
sbi
You sir, are a genius :) This incidentally solves like 3 other issues my old method had.
Joseph Garvin
Also at the time of this posting our scores match exactly, kind of cool coincidence.
Joseph Garvin
@Joseph: Glad it helps. `:)`
sbi
A: 

[deleted incorrect response]

John Deters
Actually, I think you can use `char*` objects as a template parameters. That is, different strings create different template instances. IIRC, the strings have to have external linkage, though.
sbi
@jadeters: You're confusing template type parameters and template value parameters. The template is instantiated differently for different address values, not for different types. See the factorial example here to understand what I'm doing, just with const char* instead of int:http://en.wikipedia.org/wiki/Template_metaprogramming
Joseph Garvin