iterator_traits <InIter> :: value_type的创建是否会在传递时触发deference?(例外测试)

Syn*_*ose 5 c++ boost iterator exception c++11

我故意为那些不是特定的deference迭代器的函数故意抛出异常(用于测试目的).要了解我在做什么,请采取我的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;
    };
Run Code Online (Sandbox Code Playgroud)

decorator_iterator 让我将回调附加到在取消引用时触发的迭代器,使用此我可以测试抛出异常

try {

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

这个函数非常适合我的一些特定取消引用指针的实现,例如

[](reference it) {
    //triggers callback
    *it = ...
}
Run Code Online (Sandbox Code Playgroud)

我现在的问题是当我正在进行并行执行时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));

}
Run Code Online (Sandbox Code Playgroud)

注意:我尝试简单地修改lambda以传入InIter ref和使用*ref但不会起作用并且会给我错误.

seh*_*ehe 0

迭代器仅提供一组明确定义的操作。

除了使用标准定义的取消引用操作(间接运算符或)之外,我不知道任何其他(明确定义的)取消引用迭代器的方法*it

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

跳出框框思考,一种解释可能是异常不会(立即)从工作线程传播。我不知道ExPolicy是什么,但这可能是例外政策。

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