Различные макросы для идентификации типов данных VMD дополняют возможность идентификации пустоты с помощью BOOST_VMD_IS_EMPTY. Общее название, которое я буду использовать в этой документации для этих конкретных макросов, — «идентификация макросов». Идентифицирующие макросы также делятся с BOOST_VMD_IS_EMPTY Врожденный недостаток, упомянутый при обсуждении BOOST_VMD_IS_EMPTY, поскольку они сами используют BOOST_VMD_IS_EMPTY, чтобы определить, что вход закончился.
Для повторного описания дефекта с помощью BOOST_VMD_IS_EMPTY:
- при использовании стандартного компилятора C++, если вход заканчивается именем функционального макроса, и этот макрос принимает два или более параметров, произойдет ошибка предварительной обработки.
- Используя компилятор VC++, если вход состоит из имени функционального макроса, и этот макрос при вызове без параметров возвращает кортеж, макрос ошибочно возвращает 1, что означает, что вход пуст.
- Даже если функциональный макрос принимает один параметр, переход пустоты к этому макросу может вызвать ошибку предварительной обработки.
Очевидным способом избежать проблемы BOOST_VMD_IS_EMPTY с идентифицирующими макросами является проектирование ввода так, чтобы имя функционального макроса никогда не передавалось в качестве параметра. Это может быть сделано, если вы используете VMD и имеете ситуации, когда вход может содержать функциональное макро-имя, имея это функциональное макро-имя, помещенное в тип данных Boost PP, такой как кортеж, без попытки идентифицировать тип элемента кортежа с использованием VMD. Другими словами, если ввод:
( SOME_FUNCTION_MACRO_NAME )
У нас есть макроопределение:
#define SOME_FUNCTION_MACRO_NAME(x,y) some_output
VMD все еще может анализировать входные данные в виде кортежа, если это необходимо, используя BOOST_VMD_IS_TUPLE, не сталкиваясь с проблемой BOOST_VMD_IS_EMPTY. Однако, если вход:
SOME_FUNCTION_MACRO_NAME
либо непосредственно, либо через доступ к первому элементу вышеупомянутого кортежа, и программист пытается использовать BOOST_VMD_IS_IDENTIFIER с этим входом, будет возникать проблема BOOST_VMD_IS_EMPTY.
Идентифицирующие макросы VMD дают метапрограммисту препроцессора большую гибкость при проектировании макросов. Это не просто гибкость, позволяющая прямым параметрам макроса быть разными типами данных, и иметь макро-работу по-разному в зависимости от типа передаваемых ему данных, но также гибкость, позволяющая отдельным элементам данных более высокого уровня Boost PP быть разными типами данных и иметь макро-работу правильно в зависимости от типа типа данных, передаваемых как часть этих элементов.
С этой гибкостью также приходит большая ответственность. Для макродизайнера эта ответственность двойная:
- Тщательно документировать возможные комбинации приемлемых данных и их значение.
- Чтобы сбалансировать гибкость с простотой использования, чтобы макрос не стал настолько трудным для понимания, что программист, ссылающийся на макрос, полностью отказывается от его использования.
Для программиста, использующего макрос, ответственность заключается в том, чтобы понять документацию и не пытаться передать макроданные, которые могут привести к неправильным результатам или ошибкам предварительной обработки.