迭代器的验证
Validation of Iterator
我在 C++03 项目中工作。我正在将迭代器放入模板中。我需要断言此迭代器引用特定类型。 除了编写自己的验证结构之外,C++ 是否提供了一种方法来执行此操作?
我想要的是这个 C++14 功能的等价物:
static_assert(is_same<iterator_traits<InputIterator>::value_type, int>(), "Not an int iterator");
因为它是 C++03,所以我假设我必须使用 assert
,如果它只是运行时调试检查,那很好,我只需要检查就在那里。
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中已经存在,添加注释会在编译错误中出现
由于题目的参数是:
A way to do this beyond writing my own struct for validation
并且假定:
I'll have to use an assert
and that's fine if it's a runtime only debug check
您可以在 C++03 中使用 typeid
:
assert(typeid(iterator_traits<InputIterator>::value_type) == typeid(int));
我在 C++03 项目中工作。我正在将迭代器放入模板中。我需要断言此迭代器引用特定类型。 除了编写自己的验证结构之外,C++ 是否提供了一种方法来执行此操作?
我想要的是这个 C++14 功能的等价物:
static_assert(is_same<iterator_traits<InputIterator>::value_type, int>(), "Not an int iterator");
因为它是 C++03,所以我假设我必须使用 assert
,如果它只是运行时调试检查,那很好,我只需要检查就在那里。
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中已经存在,添加注释会在编译错误中出现
由于题目的参数是:
A way to do this beyond writing my own struct for validation
并且假定:
I'll have to use an
assert
and that's fine if it's a runtime only debug check
您可以在 C++03 中使用 typeid
:
assert(typeid(iterator_traits<InputIterator>::value_type) == typeid(int));