Учитывая текст в #define, можно ли его каким-то образом передать в шаблон?

Скажем, у меня есть макрос FOO(name) и некоторый класс шаблона Bar‹>, который принимает один параметр (какой тип параметра — вопрос). Каждый раз, когда я вызываю FOO с другим именем, я хочу получить другой экземпляр Bar. Шаблон Bar‹> на самом деле не должен иметь возможность получить внутреннее имя, мне просто нужно быть уверенным, что разные имена создают разные экземпляры Bar‹> и что использование одного и того же имени (даже в разных единицах перевода) всегда получает тот же экземпляр Bar‹>. Итак, вот грубая первая попытка:

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

#define FOO(name) Bar<#name>

Это будет работать, за исключением того, что литералы char нельзя передавать в качестве параметров шаблона, поскольку они не имеют внешней связи. Если бы в препроцессоре был какой-то способ получить непротиворечивый хэш «имени», чтобы сказать, int (который затем может быть передан в шаблон), это сработало бы, но я не вижу никакого способа сделать это.

Идеи?


person Joseph Garvin    schedule 10.08.2009    source источник
comment
Что именно ты пытаешься сделать?   -  person GManNickG    schedule 11.08.2009
comment
Нелепое злоупотребление языком C++ ;) Это будет частью библиотеки с открытым исходным кодом, которая скоро будет выпущена, я прокомментирую здесь, как только это будет сделано, чтобы вы могли видеть ;)   -  person Joseph Garvin    schedule 11.08.2009
comment
Это использовалось в реализации TOAST_STATIC_INIT_PROTECTED для библиотеки Toast с открытым исходным кодом в версии 1.2. Ссылка на документацию: toast.sourceforge.net/   -  person Joseph Garvin    schedule 28.10.2009


Ответы (1)


В зависимости от того, где вы собираетесь использовать этот макрос (пространство имен или область действия класса), вы можете создать тип тега и использовать его:

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

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

Если это не сработает, возможно, вы можете заранее «объявить» эти имена:

#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);
person sbi    schedule 10.08.2009
comment
ты точно имеешь в виду template<typename T>? - person bdonlan; 11.08.2009
comment
@bdonlan: Хм, да, я просто скопировал код, особо не задумываясь. Прости. Починю. - person sbi; 11.08.2009
comment
Вы, сэр, гений :) Кстати, это решает, как и 3 другие проблемы, которые были у моего старого метода. - person Joseph Garvin; 11.08.2009
comment
Кроме того, на момент написания этой публикации наши оценки точно совпадают, что-то вроде классного совпадения. - person Joseph Garvin; 11.08.2009