“random_shuffle”:不是“std”的成员错误。

8

我试图使用std::random_shuffle,但是出现了编译错误。

我的编译器是v140(Visual Studio 2015),并且我在x64、发布模式下工作。

我的代码:

#include <random>
#include <algorithm>
void foo()
{
    std::vector<int> v;
    std::random_shuffle(v.begin(), v.end());
}

我收到的错误信息:

error C2039: 'random_shuffle': is not a member of 'std'
error C3861: 'random_shuffle': identifier not found
  • 有任何想法是什么问题吗?

谢谢!


2
http://en.cppreference.com/w/cpp/algorithm/random_shuffle - LogicStuff
2
@LogicStuff:这已经在问题中链接了。你的观点是什么? - Ben Voigt
1
@BenVoigt的观点是指,指定的页面清楚地说明他做错了什么。 - mrogal.ski
2
@m.rogalski:指定的页面没有任何线索说明出了什么问题。他包含了正确的头文件,即使他的参数不兼容,他也应该有一个std::random_shuffle。我怀疑编译器安装的头文件集合已经损坏。 - Ben Voigt
2
@BenVoigt - 该页面上写着“直到C++17”。因此,如果将代码编译为C++17,这将导致在std命名空间中未定义该标识符。我认为该页面提供了一个相当重要的提示。 - StoryTeller - Unslander Monica
显示剩余8条评论
3个回答

35

random_shuffle在C++14中已被弃用,在C++17中完全删除。

您需要使用带有随机生成器参数的shuffle

您可以在该网站上看到一个简单的示例:

std::random_device rd;
std::mt19937 g(rd());

std::shuffle(v.begin(), v.end(), g);

n4190

删除 auto_ptr、random_shuffle() 和旧内容

...

III.必须去除的部分

D.12 "随机洗牌"[depr.alg.random.shuffle]

这定义了random_shuffle(first, last)和random_shuffle(first,last,rng)。(后者使用RandomNumberGenerator,其要求与C++11的UniformRandomNumberGenerator完全不同。)

random_shuffle(first,last)的问题在于它可以使用rand(),而rand()被允许是低质量的。(rand()甚至被允许引入数据竞争,26.8 [c.math] / 5,尽管我不知道有任何实现这样做。)构造mt19937 urng并调用shuffle(first,last,urng)是一个远远优于此的选择。

与random_shuffle(first,last)不同,调用shuffle(first,last,urng)需要用户意识到URNG(均匀随机数生成器)的存在和状态,但我认为这是一种特色,而不是错误。

random_shuffle (first,last,rng)是Knuth shuffle算法。它不邪恶,但在实践中几乎无法使用,因为需要“rng”函数对象提供非常奇怪的界面。(实际上需要返回一个不同间隔上的均匀整数分布,这很难做到而不引入偏差。) shuffle(first,last,urng)更容易使用,因为它直接消耗URNG。


Visual Studio C++标准版本。

与gcc或clang不同,Visual Studio没有提供选择标准版本的选项,因此弹出的问题是:VS实现哪个C++标准?答案是...两者都不是...并且每种标准都有一点。我最后检查时,他们的哲学是努力慢慢达到最新的标准版本,但不是按照标准版本步骤,也就是说,在C + 11还没有完全实现时,他们正在实现C + +14功能。因此,您将看到实现了C ++ 11的某些部分,实现了C ++ 14的某些部分,以及实现了C ++ 17的某些部分。


4
这不是std::random_shuffle的例子,他得到的编译错误与传递错误数量的参数不一致。 - Ben Voigt
2
这个回答根本没有解决问题。 - Galik
3
Q: "我遇到错误:'random_shuffle': is not a member of 'std'" A: "random_shuffle已被删除" 这个回答已经解答了问题。 - bolov
1
据我所知,random_shuffle 函数并未在 VS2015 中被删除,并且也没有在当前版本的 C++ 标准中被删除。 - Galik
3
@Galik,这与 c++17 有什么关系?事实1:OP 在 Visual Studio 中遇到了有关未在 std 中找到函数的错误。事实2:该函数已在 C++17 中被删除。事实3:Visual Studio 正在实施 C++17 的功能。 - bolov
显示剩余5条评论

8
使用工具链v140的默认设置编译代码是没有问题的。但是,如果您添加选项/std:c++latest,可能会无法再使用部分标准库。这可能是为了尽可能接近C++17标准而做出的尝试。

1
符合规范的实现不允许删除标准库已弃用的部分。它可以删除已经被移除的部分;但是弃用并不等于移除。 - Pete Becker

1

简述:

我在使用Visual Studio时遇到了这个错误。
要解决这个问题,只需在属性 > C/C++ > 命令行中设置/Zc:__cplusplus标志,然后您就可以继续了。

详细说明:

我在尝试使用Hayai时遇到了此问题。在Visual Studio中,__cplusplus始终设置为199711L,并且也因此在Visual Studio中检查失败了,因为Hayai也会检查它。

        /// Randomly shuffles the order of tests.
        static void ShuffleTests()
        {
            Benchmarker& instance = Instance();
#if __cplusplus > 201100L
            std::random_device rd;
            std::mt19937 g(rd());
            std::shuffle(instance._tests.begin(),
                         instance._tests.end(),
                         g);
#else
            std::random_shuffle(instance._tests.begin(),
                                instance._tests.end());
#endif
        }

正如你所看到的,由于Visual Studio中的这个问题,它总是分支到错误的片段,因此失败。
要解决这个问题,只需在“属性>C/C++>命令行”中设置/Zc:__cplusplus标志即可。
来自Microsoft:

/Zc:__cplusplus编译器选项使得__cplusplus预处理宏能够报告最近C++语言标准支持的更新值。默认情况下,Visual Studio总是为__cplusplus预处理宏返回值“199711L”。

备注


__cplusplus预处理宏通常用于报告特定版本的C++标准的支持。因为许多现有代码似乎依赖于该宏的值与“199711L”匹配,所以编译器不会更改宏的值,除非您显式选择使用/Zc:__cplusplus编译器选项。从Visual Studio 2017版本15.7开始提供/Zc:__cplusplus选项,默认情况下关闭。在较早版本的Visual Studio中,默认情况下或者指定了/Zc:__cplusplus,Visual Studio为__cplusplus预处理宏返回值“199711L”。/permissive选项不会启用/Zc:__cplusplus

当启用/Zc:__cplusplus选项时,__cplusplus宏报告的值取决于/std版本开关设置。这张表格显示了宏的可能值:

请务必阅读实际文章这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接