Как я могу сделать утверждения времени компиляции без С++ 11
На собеседовании меня попросили написать метафунг
который определяет, был ли тип указателем. Это
что я представил:
template <typename T>
struct is_pointer
{ static const bool value = false; }
template <typename T>
struct is_pointer<T *>
{ static const bool value = true; }
Затем меня попросили написать мета-утверждение, которое не получится
во время компиляции, если моя функция is_pointer
не является
делать правильные вещи.
Когда я использовал static_assert
, он прямо сказал мне, что
Я могу использовать только стандарт С++ 98. Как я могу достичь этого?
Ответы
Ответ 1
В вашем случае
template <bool> struct assert;
template <> struct assert<true> {};
решил бы проблему:
assert<!is_pointer<char>::value>(); // valid
assert<is_pointer<char *>::value>(); // valid
assert<is_pointer<char>::value>(); // compilation error:
// use of incomplete class
Ответ 2
Существуют разные подходы, один из которых пытается ввести неверный тип:
#define static_assert(condition) \
typedef char assert ## __LINE__ [((condition)?1:-1)]
Это может использоваться в основном в любом контексте и отключит компилятор, если условие ложно, поскольку оно попытается ввести typedef недопустимый тип (массив отрицательного числа элементов). Его можно использовать в разных контекстах:
// namespace level:
static_assert(sizeof(int)==4);
struct type {
// class level:
static_assert(sizeof(int)==4);
void f() {
// function level
static_assert(sizeof(int)==4);
}
};
Ответ 3
Я бы использовал BOOST_STATIC_ASSERT
. Вы можете посмотреть код: boost/static_assert.hpp.
Здесь очень упрощенная версия, просто чтобы дать вам идею:
#define JOIN(X, Y) DO_JOIN(X, Y)
#define DO_JOIN(X, Y) X ## Y
template<bool cond>
struct Static_assert_helper; // incomplete type
template<>
struct Static_assert_helper<true> {
typedef int Type;
};
#define STATIC_ASSERT(cond) \
typedef Static_assert_helper<(cond)>::Type JOIN(Static_assert_typedef_, __LINE__)
Его можно использовать во многих местах (см. документацию для примеров).
(реализация Boost более полная, например, sizeof
и промежуточная структура, чтобы дать лучшее сообщение об ошибке и быть переносимым в широком диапазоне компиляторов.)