2

私は C++03 プロジェクトで作業しています。そして、イテレータをテンプレートに取り込んでいます。この反復子が特定の型を参照していると断言する必要があります。C++ は、検証のために独自の構造体を作成する以外に、これを行う方法を提供してくれますか?

私が欲しいのは、この C++14 機能と同等のものです。

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

これは C++03 であるため、使用する必要があると思います。assert実行時のみのデバッグ チェックであれば問題ありません。チェックが必要なだけです。

4

2 に答える 2

3

static_assertC++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_traitsC++03 には既に存在しており、コメントを追加すると、メッセージがコンパイル エラーに表示されます。

于 2015-08-05T13:39:26.783 に答える
0

質問のパラメータは次のとおりです。

検証のために独自の構造体を書く以外にこれを行う方法

そして、それは仮定されます:

を使用する必要がありますがassert、ランタイムのみのデバッグ チェックであれば問題ありません。

typeidC++03 で使用できます。

assert(typeid(iterator_traits<InputIterator>::value_type) == typeid(int));
于 2015-08-05T14:05:49.223 に答える