Используйте static_assert для проверки типов, передаваемых в макрос - PullRequest
21 голосов
/ 26 октября 2010

К сожалению, у меня осталось несколько макросов от исходной версии моей библиотеки, в которой использовался довольно сумасшедший C. В частности, у меня есть серия макросов, которые ожидают, что им будут переданы определенные типы. Можно ли сделать что-то вроде:

static_assert(decltype(retval) == bool);

А как? Есть ли какие-нибудь умные альтернативы?

Да, я знаю, что макросы плохие. Я знаю, что C ++ - это не C и т. Д.

Update0

Вот некоторый связанный код и исходный файл . Предложения приветствуются. Оригинальный вопрос остается прежним.

Ответы [ 4 ]

46 голосов
/ 27 октября 2010

Я нашел это самое чистое, используя @ UncleBens предложение:

#include <type_traits>

static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
3 голосов
/ 26 октября 2010

Кажется, вам нужно decltype, потому что у вас есть выражение, но вы хотите проверить тип.Уже есть достаточно способов сделать это (C ++ 03).Например, чтобы проверить bool

inline void mustBeBool(bool) { }
template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)

// Use:
#define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)
2 голосов
/ 26 октября 2010

Отказ от ответственности: это плохой ответ, безусловно, есть гораздо лучшие решения. Просто пример:)

Он обязательно должен быть реализован, но реализовать его тривиально;

template <class T1, class T2> struct CheckSameType; //no definition
template <class T> struct CheckSameType<T,T>{}; //

template <class T1, class T2>
AssertHasType(T2)
{
   CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
}

Для использования следующим образом:

AssertHasType<bool>(retval);

Альтернатива (предложено GMan):

template <class T1, class T2> struct SameType
{
    enum{value = false};
}
template <class T> struct SameType<T,T>
{
    enum{value = true};
}; 

Используется как

static_assert(SameType<decltype(retval), bool>::value);
1 голос
/ 26 октября 2010

Большинство макросов могут быть заменены на inline функции и / или шаблоны.Как пример, слишком умный макрос Posix isnan для проверки размера аргумента является шаблоном в C ++ 0x.О, плохой пример, но вы поняли.

Основными исключениями из этого правила являются макросы, которые по существу реализуют функции language более высокого уровня.Например, более разумная обработка исключений или ковариация, или параметризованный набор объявлений.

В некоторых случаях макросы, которые не могут быть разумно выражены как inline функции или шаблоны, могут быть заменены более умнымпредварительной обработки, а именно генерация кода.Тогда у вас есть сценарий, который генерирует необходимый код.Например, можно создать классы параметров в чистом C ++ с макросами и шаблонами, но это сложно, и в качестве более простой в использовании и, возможно, более удобной альтернативы можно использовать сценарий, который генерирует необходимые классы, за счет дополнительных затрат.строить шаги и работать с несколькими языками.

Cheers & hth.,

...