c++ - 将自定义仿函数与 std::generate_n() 算法一起使用的正确方法?

标签 c++ stl functional-programming

以下代码在 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/

相关文章:

http - testng - 登录后的 HTTP REST 测试

lambda - Java 8 中的 lambda 表达式如何支持函数式编程?

c++ - 如何在C++中写小数点后两位数?

c++ - 在无序映射中实现无序映射

c++ - 使用 Protocol Buffer 发送图标/小图像

c++ - 在 C++ 中初始化静态 std::map<int, int>

javascript - react 没有在输入更改时更新功能组件状态

c++ - c++中下列表达式的含义是什么

c++ - 结构体的 sizeof 会受到数组元数据的影响吗?

c++ - 至少出现两次的最长子串 : C++ question