创建 <InIter>iterator_traits::value_type 在通过时会触发尊重吗?(异常测试)

Will the creation of an iterator_traits<InIter>::value_type trigger a deference when passed? (Exception testing)

本文关键字:测试 异常 iterator gt InIter lt traits value 创建 type 过时      更新时间:2023-10-16

我在故意抛出异常(出于测试目的)时遇到了麻烦,因为函数没有明确地遵从迭代器。为了了解我在做什么,取我的decorator_iterator结构体:

struct decorated_iterator
      : boost::iterator_adaptor<
            decorated_iterator<BaseIterator, IteratorTag>,
            BaseIterator, boost::use_default, IteratorTag>
    {
        //....
    private:
        friend class boost::iterator_core_access;
        /* used to throw an exception upon dereference */
        typename base_type::reference dereference() const
        {
            m_callback();
            return *(this->base());
        }
    private:
        std::function<void()> m_callback;
    };

decorator_iterator允许我将回调附加到解引用触发的迭代器上,使用这个我可以测试异常抛出

try {
    copy(
        decorated_iteartor(iter, [](){throw std::runtime_error("test");}),
        decorated_iterator(iter, [](){}),
        begin(destiter));
}
//catch runtime!

这个函数对于我的一些具体解引用指针的实现非常有效,例如

[](reference it) {
    //triggers callback
    *it = ...
}

我现在的问题是当我在std::count的并行实现上工作时,我所有的异常测试都失败了。我的猜测是,我从来没有特别在lambda函数中解引用迭代器,而是使用iterator_traits<InIter>::value_type。如果值类型不会解引用,我可以在decorator_iterator或我的函数中修改什么来导致回调被执行?给我带来麻烦的特定计数过载:

template <typename ExPolicy, typename InIter, typename T>
typename detail::algorithm_result<ExPolicy, 
    typename std::iterator_traits<InIter>::difference_type>::type
count(ExPolicy const& policy, InIter first, InIter last, const T& value,
boost::mpl::false_ f)
{
    //get a value_type to compare to passed value
    typedef typename std::iterator_traits<InIter>::value_type type;
    typename std::iterator_traits<InIter>::difference_type ret = 0;
    //from first to last, execute the following lambda
    for_each_n(policy,
        first, std::distance(first,last),
        [&value, &ret](type v) {
            if (v == value)
                ret++;
        }, f);
    return detail::algorithm_result<ExPolicy, 
        typename std::iterator_traits<InIter>::difference_type>::get(std::move(ret));
}

注意:我尝试简单地修改lambda传递在InIter ref和使用*ref,但这不会工作,会给我错误。

迭代器只提供一组定义良好的操作。

除了使用标准定义的解引用操作(间接操作符,或*it)之外,我不知道还有其他(定义良好的)解引用迭代器的方法。

你可以看到对std::vector::iterator进行优化的实现(例如,如果元素类型是POD,则使用memcpy/memmov)。然而,我认为对于库(在本例中是并行算法库)来说,对用户提供的迭代器做出这样的假设是一个坏主意。换句话说,如果标准库检测到基本迭代器类型并对其进行优化,使绕过了用户定义迭代器的副作用,那么在我看来,将是一个严重的错误

开箱即用,一个解释可能是异常没有(立即)从工作线程传播。我不知道ExPolicy是什么,但它可能是一个例外策略。

我可以完全想象该算法返回future<size_t>(可能取决于ExPolicy参数),因此您不会看到异常,直到您.get() 的值的未来?