2

我在一个 C++03 项目中工作。我正在将迭代器放入模板中。我需要断言这个迭代器引用了一个特定的类型。除了编写我自己的结构进行验证之外,C++ 是否为我提供了一种方法来做到这一点?

我想要的是这个 C++14 功能的等价物:

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

由于它是 C++03,我假设我必须使用 anassert并且如果它是一个仅运行时的调试检查,我只需要检查就可以了。

4

2 回答 2

3

C++03 没有static_assert-type 的东西,这是 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,将其转换为 a 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 中已经存在,添加注释会让消息显示在编译错误中。

于 2015-08-05T13:39:26.783 回答
0

由于问题的参数是:

除了编写我自己的结构进行验证之外,还有一种方法可以做到这一点

并且假设:

我将不得不使用一个assert,如果它只是一个运行时调试检查,那很好

您可以typeid在 C++03 中使用:

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