如何使用 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" 终止程序,如果您迭代越界。
我有以下代码将 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" 终止程序,如果您迭代越界。