如何使用 std::transform 为越界写入抛出异常?

How to throw exception for out of bounds write with std::transform?

我有以下代码将 std::vector a 复制到另一个 std::vector b,但以 2 作为起始索引。由于两个向量的长度均为 4,因此这会导致越界写入。我想让这段代码抛出异常,但我该怎么做呢?下面的代码因分段错误而崩溃。

#include <vector>
#include <iostream>

int main()
{
    std::vector<double> a = {1, 2, 3, 4};
    std::vector<double> b(4);

    try
    {
        std::transform(a.begin(), a.begin()+4, b.begin()+2,
                [](const double d) { return d; });
    }
    catch (std::exception& e)
    {
        std::cout << "EXCEPTION: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

std::transform 假定 [d_first, d_first+std::distance(first1, last1)) 有效。

但是您可以编写自己的算法,如果您也将 "end" 迭代器添加到输出范围:

template <typename InputIt, typename OutputIt, typename UnaryOp>
OutputIt safe_transform(
   InputIt first1, InputIt last1,
   OutputIt first2, OutputIt last2,
   UnaryOp unary_op )
{
    while ( first1 != last1 ) {
        if ( first2 == last2 )
            throw std::domain_error( "Reached end of output range" );
        *first2 = unary_op( *first1 );
        ++first1;
        ++first2;
    }
    return first2;
}

transform 在后台取消引用它的迭代器。没有任何方法可以让它调用 at(),这是 operator[] 的边界检查版本。您可以使用 -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC 启用调试容器,其中 libstdc++ 将使用 "safe iterators" 终止程序,如果您迭代越界。