简体   繁体   English

验证迭代器

[英]Validation of Iterator

I am working in a C++03 project. 我正在C ++ 03项目中工作。 And I'm taking an iterator into a template. 我正在将迭代器放入模板中。 I need to assert that this iterator references a specific type. 我需要断言该迭代器引用特定类型。 Does C++ provide me a way to do this beyond writing my own struct for validation? 除了编写自己的结构进行验证之外,C ++是否为我提供了做到这一点的方法?

What I want is the equivalent of this C++14 functionality: 我想要的就是这个C ++ 14功能的等效项:

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

Since it's C++03 I assume that I'll have to use an assert and that's fine if it's a runtime only debug check I just need the check to be there. 由于它是C ++ 03,因此我假设我必须使用一个assert ,如果这是仅运行时的调试检查,那很好,我只需要检查就可以了。

C++03 doesn't come with a static_assert -type thing, that's a C++11 feature. C ++ 03并没有带有static_assert类型的东西,这是C ++ 11的功能。 However, there's BOOST_STATIC_ASSERT . 但是,有BOOST_STATIC_ASSERT If Boost is not available to you, then this is actually a fairly straightforward thing to write: 如果您无法使用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))

The idea is that, we take our expression B , convert it to a bool , and use that in a context where if it's true , we'll have a complete type, and if it's false , we won't. 这个想法是,我们将表达式B转换为bool ,并在上下文中使用它,如果它为true ,我们将拥有一个完整的类型,而如果它为false ,我们将不会。 You cannot take sizeof() an incomplete type, so that'll be a compile error. 您不能将sizeof()作为不完整的类型,所以这将是编译错误。

So if I did: 因此,如果我这样做了:

MY_STATIC_ASSERT(sizeof(int) >= 5);

gcc gives me: 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); 
     ^

It's not quite as nice as: 它不如:

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

but then, that's what happens when you don't have a language feature. 但是,当您没有语言功能时,就会发生这种情况。


With that, we can convert: 这样,我们可以转换:

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

To: 至:

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 already existed in C++03, and adding a comment will let the message show up in the compile error. iterator_traits在C ++ 03中已经存在,添加注释将使消息显示在编译错误中。

Since the parameters of the question are: 由于问题的参数是:

A way to do this beyond writing my own struct for validation 除了编写我自己的结构进行验证之外,还有一种方法可以做到这一点

And it is assumed: 假设:

I'll have to use an assert and that's fine if it's a runtime only debug check 我必须使用assert ,如果仅是运行时调试检查就可以了

You can use typeid in C++03: 您可以在C ++ 03中使用typeid

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM