簡體   English   中英

std :: generate_n的函子能夠安全地捕獲和操作用於填充的容器嗎?

[英]Is it safe for std::generate_n's functor to capture and operate on container it's used for populating?

最近,我一直在使用STL算法和lambda來實現非凡的功能。 幾個星期前,有人告訴我謂詞(例如, std::count_if使用的lambda)修改傳遞給它的值是非法的。

我只是接受了這一點,並記得從未嘗試過做那樣的事情。 但是,我剛剛遇到了潛在的類似情況,並且不確定使用以下代碼是否合法

auto generate_n_fib(const std::size_t count = 2) {
    assert(count != 0);
    if(count == 1) {
        return std::vector<std::size_t>{0};
    }
    if(count == 2) {
        return std::vector<std::size_t>{0, 1};
    }
    std::vector<std::size_t> fib{};
    fib.emplace_back(0);
    fib.emplace_back(1);

    if(count > 2) {
        std::generate_n(std::back_inserter(fib), count - 2, [&fib](){
            const auto last = fib.size() - 1;
            return fib[last] + fib[last - 1];
        });
    }

    return fib;
}

如您所見,上面的函數從斐波那契count生成第一個count數字。 相關的部分是std::generate_n調用。

我的問題是- 生成器函數訪問由使用該生成器函數的算法修改的集合的字段是否安全?

std::generate_n一種可能的實現是:

template< class OutputIt, class Size, class Generator >
OutputIt generate_n( OutputIt first, Size count, Generator g )
{
    for( Size i = 0; i < count; i++ ) {
        *first++ = g(); 
    }
    return first;
}

for循環中的表達式*first++與在原始向量fib調用push_back等效。 如果用該表達式代替該表達式,則for循環幾乎等效於:

for( Size i = 0; i < count; i++ ) {
    fib.push_back(g());
}

g命名拉姆達:

auto g = [&fib]() {
    const auto last = fib.size() - 1;
    return fib[last] + fib[last - 1];
};

這是很好的定義。

我們仍然可以展開操作; 除去lambda,后插入迭代器,並完成for循環中的所有工作,但有一個定義明確的代碼。

暫無
暫無

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

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