将自定义函子与std::generate_n()算法一起使用的正确方法
Correct way to use custom functor with std::generate_n() algorithm?
以下代码在XPSP3上的VC++8下正确编译,但运行它会导致运行时错误。
我的标题看起来像:
#include <stdexcept>
#include <iterator>
#include <list>
template<typename T>
class test_generator
{
public:
typedef T result_type;
//constructor
test_generator()
{
std::generate_n( std::back_inserter( tests ), 100, rand );
value = tests.begin();
}
result_type operator()( void )
{
if( value == tests.end() )
{
throw std::logic_error( "" );
}
return *value++;
}
private:
std::list<T> tests;
typename std::list<T>::iterator value;
};
我的实现看起来像:
#include <functional>
#include <algorithm>
#include <iostream>
#include <deque>
#include "test.h"
int main()
{
test_generator<double> test;
std::deque<double> tests;
std::generate_n( std::back_inserter( tests ), 10, test );
return 0;
}
这编译得很好,它会生成一个异常(而不是标头中定义的logic_error异常)。
如果我将实现更改为使用函数而不是函子,它会起作用:
int main()
{
std::deque<int> tests;
std::generate_n( std::back_inserter( tests ), 10, rand );
return 0;
}
在这里使用函子有什么问题?
test_generator
构造函数初始化value
迭代器以引用tests
列表中的第一个元素(它是test_generator
的成员)。
调用std::generate_n
时,会生成test
的副本(因为对象是按值传递的)。在复制的对象中,value
迭代器指的是原始对象中的tests
列表,而不是副本。
由于在Visual Studio STL实现中执行迭代器调试检查,因此这会触发断言,因为从一个容器获得的迭代器不应与另一个容器中的迭代程序进行比较。
为了解决这个问题,您可以为test_generator
类实现一个复制构造函数,或者将value
的初始化推迟到第一次调用operator()
。
到目前为止,我还没有弄清楚是什么导致了异常,但您可能希望在operator()
中包含return *value++
。:-)
相关文章:
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 如何将enable-if与模板参数和参数包一起使用
- 如何将PERF_AMPLE_READ与mmap一起使用
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 如何将C++中的库和头与MinGW一起使用
- 我可以将CRTP与虚拟函数或函数一起使用,以供访问者算法更改的访问者算法
- 将 emplace 与 std::fill 等算法一起使用
- 将我的自定义迭代器与 STL 算法一起使用
- 哪些 STL 算法可以安全地与单通道输入迭代器一起使用
- 如何将输入文件中的坐标与 prim 算法一起使用,以便使用pygraphics和C++创建圆?
- 在std::list中合并(将两个项目融合在一起,用融合替换)项目的算法(即破坏性聚类)
- c++STL算法remove_if与模板一起使用
- STL算法可以与循环列表一起使用吗?
- 算法partition_copy()在SIGABRT中产生,与back_inserter一起工作
- 将自定义函子与std::generate_n()算法一起使用的正确方法