std :: shuffle不能用std :: list编译

thu*_*ove 5 c++ shuffle list std

我试图改组一些生成的元素列表.这是代码:

std::default_random_engine generator (10);
std::list<int> list(10);

int n = 0;
std::generate(list.begin(), list.end(), [&]{ return n++; });
std::shuffle(list.begin(), list.end(), generator);
Run Code Online (Sandbox Code Playgroud)

它没有编译.以下是错误:

/include/c++/v1/algorithm:3059:34: Invalid operands to binary expression ('std::__1::__list_iterator<int, void *>' and 'std::__1::__list_iterator<int, void *>')
main.cpp:1:10: In file included from main.cpp:1:

/include/c++/v1/random:1641:10: In file included from /bin/../include/c++/v1/random:1641:

main.cpp:37:10: In instantiation of function template specialization 'std::__1::shuffle<std::__1::__list_iterator<int, void *>, std::__1::linear_congruential_engine<unsigned int, 48271, 0, 2147483647> &>' requested here
/include/c++/v1/iterator:622:1: Candidate template ignored: could not match 'reverse_iterator' against '__list_iterator'
/include/c++/v1/iterator:1017:1: Candidate template ignored: could not match 'move_iterator' against '__list_iterator'
/include/c++/v1/iterator:1369:1: Candidate template ignored: could not match '__wrap_iter' against '__list_iterator'
/include/c++/v1/string:486:11: Candidate template ignored: could not match 'fpos' against '__list_iterator'
Run Code Online (Sandbox Code Playgroud)

有人有任何想法吗?

And*_*owl 13

std::list不提供对其元素的随机访问,这std::shuffle()需要.这就是std::shuffle()其规范中的签名(C++标准第25.3.12段):

template<class RandomAccessIterator, class UniformRandomNumberGenerator>
void shuffle(RandomAccessIterator first,
             RandomAccessIterator last,
             UniformRandomNumberGenerator&& g);
Run Code Online (Sandbox Code Playgroud)

如果可以,请考虑使用std::vector- 而顺便说一下,鼓励您使用C++标准本身作为默认顺序容器.

作为一个例子(Coliru的现场演示):

int main()
{
    std::default_random_engine generator(10);
    std::vector<int> v(10);

    std::iota(begin(v), end(v), 0);
    std::shuffle(begin(v), end(v), generator);

    for (auto x : v) { std::cout << x; }
}
Run Code Online (Sandbox Code Playgroud)

std::iota()算法只是您特定用法的简单替代方法std::generate.


jua*_*nza 8

std::shuffle需要随机访问迭代器.std::list不提供那些.你需要一个不同的容器,比如std::vector.

如果您真的需要std::list,您可能需要在专用算法中实现混洗.但首先要确保你真的需要它.很多时候人们认为std::list他们真正需要时需要std::vector.