У меня есть макрос, который создает для меня класс. Я хочу предоставить конструктор, который принимает int, если сам класс не имеет int, указанный в его типе. Макрос выглядит что-то вроде:Условное расширение препроцессора C++ на основе параметра
CLASS_DECLARE(NAME, TYPE)\
class NAME { \
public: NAME(const TYPE& x) : value(x) {}\
private: TYPE value; };
Я могу приблизиться с помощью наддува препроцессор вручную превратить этот конструктор и выключается ...
CLASS_DECLARE(NAME, TYPE)\
class NAME { \
public: NAME(const TYPE& x) : value(x) {}\
BOOST_PP_EXPR_IF(0, NAME(const int& x) : value(static_cast<TYPE>(x)) {})\
private: TYPE value; };
Однако, я не могу заменить в макросе с условным. Я хочу что-то вроде:
CLASS_DECLARE(NAME, TYPE)\
class NAME { \
public: NAME(const TYPE& x) : value(x) {}\
BOOST_PP_EXPR_IF(BOOST_PP_NOT_EQUAL(TYPE, int), NAME(const int& x) : value(static_cast<TYPE>(x)) {})\
private: TYPE value; };
Однако, расширяющийся к чему-то меньше, чем полезно:
BOOST_PP_EXPR_IIF_BOOST_PP_BOOL_BOOST_PP_NOT_EQUAL_CHECK_BOOST_PP_NOT_EQUAL_int(0,
BOOST_PP_NOT_EQUAL_int)(MyType(const int& x) : value(static_cast<int>(x)){};
Осмотревшись, она не кажется, как будто BOOST_PP_NOT_EQUAL предназначен для данного типа сравнения. (Я знаю о проблемах с макрораспределением и создаю несколько макросов «IMPL», чтобы попытаться расширить возможности. Однако я не думаю, что это проблема.) Мысли?
Ваша точная проблема просто неоднозначные вызовы конструктора? И почему бы не использовать шаблоны? – Petr
Я не думаю, что вам удастся сравнить имена типов в препроцессоре, если у вас по крайней мере нет конечного набора типов. Однако вы можете передать это на этап компиляции, а не на этапе предварительной обработки. – chris
Это так. Я не могу использовать шаблоны здесь из-за других шаблонных функций и классов, которые должны использовать эти классы. Тогда это наложило бы зависимость порядка от # include. Это беспорядок. На самом деле это была моя первая попытка. MSVC был счастлив, но GCC и Clang справедливо жаловались. – DiB