简体   繁体   中英

'random_shuffle': is not a member of 'std' error

I'm trying to use std::random_shuffle , and get a compilation error.

My compiler is v140(Visual Studio 2015), and I work on x64, Release mode.

My code:

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

The errors which I get:

error C2039: 'random_shuffle': is not a member of 'std'
error C3861: 'random_shuffle': identifier not found
  • Any idea what could the problem be?

Thanks!

random_shuffle was deprecated in C++14 and completely removed in C++17.

You need to use shuffle which takes a random generator as parameter.

You can see a simple example on the site:

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

n4190

Removing auto_ptr, random_shuffle(), And Old Stuff

...

III. What Must Die

D.12 "Random shuffle" [depr.alg.random.shuffle]

This defines random_shuffle(first, last) and random_shuffle(first, last, rng). (The latter takes a RandomNumberGenerator, whose requirements are totally different from C++11's UniformRandomNumberGenerator.)

The problem with random_shuffle(first, last) is that it's permitted to use rand(), which is permitted to be low quality. (rand() is even permitted to introduce data races, 26.8 [c.math]/5, although I'm not aware of any implementation that does so.) Constructing mt19937 urng and calling shuffle(first, last, urng) is a far superior alternative. Unlike random_shuffle(first, last), calling shuffle(first, last, urng) requires the user to be aware of the URNG's existence and state, but I argue that this is a feature, not a bug.

random_shuffle(first, last, rng) is the Knuth shuffle algorithm. It's not evil, but it's almost unusable in practice, because the "rng" function object is required to provide a very strange interface. (It's actually required to return a uniform integer distribution over a varying interval, which is difficult to do without introducing bias.) shuffle(first, last, urng) is vastly easier to use, because it directly consumes a URNG.


Visual Studio C++ standard version.

Unlike gcc or clang , Visual Studio doesn't offer the option to select the standard version, so the question that pops up is: which C++ standard does VS implement? The answer is... neither... and a little of every. Last I checked their philosophy was that they strive to slowly get to the latest standard version, but not in standard versions steps, that is they were implementing C++14 features while C+11 wasn't still fully implemented. So you will see some parts of C++11 implemented, some parts of C++14 implemented and some parts of C++17 implemented.

The code compiles fine with the default settings for toolchain v140. However, if you add the option /std:c++latest , removed parts of the standard library might not be usable anymore.

Probably an attempt to get as close as possible to C++17.

TLDR:

I was in Visual Studio and faced this error.
To fix this, simply set the /Zc:__cplusplus flag in Properties > C/C++ > Command Line and you are good to go.

Long Explanation:

I faced this issue when trying to use Hayai . In visual studio the __cplusplus is always set as 199711L and Hayai that also checks for this always fails in visual studio becasue of this:

        /// 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
        }

As you can see becasue of this issue in visual studio it always branches into the wrong snippet and thus fail.
To fix this, simply set the /Zc:__cplusplus flag in Properties > C/C++ > Command Line and you are good to go.

From Microsoft:

The /Zc:__cplusplus compiler option enables the __cplusplus preprocessor macro to report an updated value for recent C++ language standards support. By default, Visual Studio always returns the value "199711L" for the __cplusplus preprocessor macro.

Remarks


The __cplusplus preprocessor macro is commonly used to report support for a particular version of the C++ standard. Because lots of existing code appears to depend on the value of this macro matching "199711L", the compiler does not change the value of the macro unless you explicitly opt-in by using the /Zc:__cplusplus compiler option. The /Zc:__cplusplus option is available starting in Visual Studio 2017 version 15.7, and is off by default. In earlier versions of Visual Studio, and by default, or if /Zc:__cplusplus - is specified, Visual Studio returns the value "199711L" for the __cplusplus preprocessor macro. The /permissive - option does not enable /Zc:__cplusplus .

When the /Zc:__cplusplus option is enabled, the value reported by the __cplusplus macro depends on the /std version switch setting. This table shows the possible values for the macro:

Make sure to read the actual article Here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM