Как я могу сделать утверждения времени компиляции без C++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
Он прямо сказал мне, что я могу использовать только стандарт C++98. Как мне этого добиться?
3 ответа
В твоем случае
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
Существуют разные подходы, один из которых пытается определить неверный тип:
#define static_assert(condition) \
typedef char assert ## __LINE__ [((condition)?1:-1)]
Это может быть использовано практически в любом контексте и отключит компилятор, если условие ложно, так как он попытается определить тип недопустимого типа (массив отрицательного числа элементов). Может использоваться в разных контекстах:
// 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);
}
};
Я хотел бы использовать 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
и промежуточная структура, чтобы дать лучшее сообщение об ошибке и быть переносимым на широкий спектр компиляторов.)