簡體   English   中英

通過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++ :-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM