Как я могу сделать утверждения времени компиляции без 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 и промежуточная структура, чтобы дать лучшее сообщение об ошибке и быть переносимым на широкий спектр компиляторов.)

Другие вопросы по тегам