作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
以下代码在 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;
}
这编译正常,它生成一个异常(不是 header 中定义的 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()
被调用。
关于c++ - 将自定义仿函数与 std::generate_n() 算法一起使用的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/231198/
我是一名优秀的程序员,十分优秀!