Есть ли способ передать
std::map<std::string, float>
как аргумент макросу?
(проблема состоит в том, что"", используется макросом для разделения
std::map<std::string
и
float>
как разделяют аргументы. Я хотел бы избежать этого.
Нет, нет способа сделать это, кроме использования typedef. BOOST_FOREACH, например, страдает той же проблемой.
Попробуйте использовать шаблон вместо макроса.
Скотт Мейерс: Эффективный C ++ Пункт 2: Предпочитайте константы, перечисления и встроенные строки #defines
Да, есть способ, но он непрямой.
Как вы уже сказали, макрос довольно туп в своей интерпретации. Однако он все равно распознает скобки.
Пример: BOOST_MPL_ASSERT((boost::is_same
Это работает за счет использования другого уровня скобок, формируя таким образом кортеж
(с точки зрения макроса).
Если вы используете библиотеку Boost.Preprocessor, вы можете легко "развернуть" Tuple
, чтобы получить его содержимое невредимым. К сожалению, предполагается, что вы должны знать размер кортежа заранее, поэтому вам нужен дополнительный параметр
#define MY_MACRO(Size, TemplatedType, Name)\
BOOST_PP_TUPLE_REM(Size)(TemplatedType) Name
И в действии:
MY_MACRO(2, (std::map<int,std::string>), idToName);
// expands to 'std::map<int,std::string> idToName'
idToName[1] = "Smith";
Итак, да, это возможно, но макрос должен быть явно адаптирован для работы с ним.
Один неэлегантный обходной путь - «спрятать» запятую внутри другого макроса
#define ARGUMENT std::map<std::string, float>
YOUR_MACRO(ARGUMENT)
#undef ARGUMENT
Однако, если ВАШ_МАКРО
сам должен передать его на другой уровень ниже в другой макрос, он столкнется с той же проблемой.
У меня было нечто подобное несколько месяцев назад, если вы используете макросы и имеете параметры, которые содержат запятые (','), вам нужно заключить их в дополнительный парентез, т.е.:
#define DEF(ret,conv,name,args) typedef ret (conv * name)(args)
//usage
DEF(void,__cdecl,Foo,(int a1, string a2));
этот метод может конфликтовать с некоторыми вещами/быть недействительным в некоторых случаях, как в этом примере (это приведет к тому, что он станет недействительным приведением в стиле c):
#define MY_VAR(type,name) type name
//usage
MY_VAR((std::map<std::string, float>),Map);
Есть один способ решить эту проблему, но он требует, чтобы ваш компилятор поддерживал переменные макросы (GCC|MSVC):
#define _W(...) __VA_ARGS__
#define VAR(x,y) x y
VAR(_W(std::map<std::string, float>),Map);