static_assert
C++03 には-typeが付属していません。これは C++11 の機能です。ただし、ありBOOST_STATIC_ASSERT
ます。ブーストが利用できない場合、これは実際にはかなり簡単に書くことができます:
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 には既に存在しており、コメントを追加すると、メッセージがコンパイル エラーに表示されます。