Проверка итератора

Я работаю в проекте C ++ 03. И я беру итератор в шаблон. Мне нужно утверждать, что этот итератор ссылается на определенный тип. Предоставляет ли мне C ++ способ сделать это помимо написания моей собственной структуры для проверки?

То, что я хочу, является эквивалентом этой функциональности C ++ 14:

static_assert(is_same<iterator_traits<InputIterator>::value_type, int>(), "Not an int iterator");

Так как это C ++ 03, я предполагаю, что мне придется использовать assert и это нормально, если это проверка времени отладки только во время выполнения, мне просто нужна проверка, чтобы быть там.

1

Решение

C ++ 03 не поставляется с static_assertвещь типа, это особенность C ++ 11. Тем не менее, есть BOOST_STATIC_ASSERT. Если Boost недоступен для вас, то написать довольно простую вещь:

namespace detail {
template <bool > struct my_static_assert;
template <> struct my_static_assert<true> { };

template <size_t > struct my_tester { };
}

#define MY_STATIC_ASSERT(B) \
typedef ::detail::my_tester< sizeof(::detail::my_static_assert< ((B) == 0 ? false : true) >)> \
my_static_assert_typedef_ ## __COUNTER__ __attribute__((unused))

Идея в том, что мы берем наше выражение B, преобразовать его в boolи использовать это в контексте, где, если это trueу нас будет полный тип, и если это falseмы не будем Вы не можете взять sizeof() неполный тип, так что это будет ошибка компиляции.

Так что, если я сделал:

MY_STATIC_ASSERT(sizeof(int) >= 5);

GCC дает мне:

main.cpp: In function 'int main()':
main.cpp:9:92: error: invalid application of 'sizeof' to incomplete type 'detail::my_static_assert<false>'
typedef detail::my_tester< sizeof(detail::my_static_assert< ((B) == 0 ? false : true) >)> \
^
main.cpp:15:5: note: in expansion of macro 'MY_STATIC_ASSERT'
MY_STATIC_ASSERT(sizeof(int) >= 5);
^

Это не так хорошо, как:

main.cpp:15:5: error: static assertion failed:
static_assert(sizeof(int) >= 5, "");
^

но это то, что происходит, когда у вас нет языковой функции.


С этим мы можем конвертировать:

static_assert(std::is_same<std::iterator_traits<InputIterator>::value_type, int>(),
"Not an int iterator");

Для того, чтобы:

namespace details {
template <typename T, typename U>
struct is_same { static const bool value = false; };

template <typename T>
struct is_same<T, T> { static const bool value = true; };
}

MY_STATIC_ASSERT(details::is_same<
std::iterator_traits<InputIterator>::value_type, int
>::value); // Not an int iterator

iterator_traits уже существовал в C ++ 03, и добавление комментария позволит сообщению появиться в ошибке компиляции.

3

Другие решения

Поскольку параметры вопроса таковы:

Способ сделать это помимо написания моей собственной структуры для проверки

И предполагается:

Я должен буду использовать assert и это нормально, если это только отладочная проверка во время выполнения

Ты можешь использовать typeid в C ++ 03:

assert(typeid(iterator_traits<InputIterator>::value_type) == typeid(int));
0

По вопросам рекламы [email protected]