Унифицированный_реалистичный оператор распределения () ошибок компиляции - PullRequest
3 голосов
/ 20 марта 2019

Я написал этот код:

std::pair<std::weak_ptr<Node>, size_t> NodeSelector::rouletteWheel() const {
    const std::uniform_real_distribution<long double> urd;
    size_t i = 0;
    for(auto rnd = urd(shared_random_engine); rnd >= 0; ++i) {
        rnd -= getNormValue(i);
    }
    return std::make_pair(entries_[i - 1], i - 1);
}

Где "shared_random_engine" инициализируется таким образом (в отдельном файле .h)

std::minstd_rand shared_random_engine(static_cast<unsigned int>(42));

Пока я компилируюэто на Windows, все работает отлично, но когда я пытаюсь скомпилировать на Ubuntu 18.04.2 с g ++ 7.3.0, я получаю эту ошибку:

montecarlo.cpp: In member function ‘std::pair<std::weak_ptr<MonteCarloNode>, long unsigned int> NodeSelector::rouletteWheel() const’:
montecarlo.cpp:728:41: error: no match for call to ‘(const std::uniform_real_distribution<long double>) (std::minstd_rand&)’
  for(auto rnd = urd(shared_random_engine); rnd >= 0; ++i) {
                                         ^
In file included from /usr/include/c++/7/random:49:0,
                 from selector.h:15,
                 from montecarlo.h:13,
                 from montecarlo.cpp:7:
/usr/include/c++/7/bits/random.h:1813:2: note: candidate: std::uniform_real_distribution<_RealType>::result_type std::uniform_real_distribution<_RealType>::operator()(_UniformRandomNumberGenerator&) [with _UniformRandomNumberGenerator = std::linear_congruential_engine<long unsigned int, 48271, 0, 2147483647>; _RealType = long double; std::uniform_real_distribution<_RealType>::result_type = long double] <near match>
  operator()(_UniformRandomNumberGenerator& __urng)
  ^~~~~~~~
/usr/include/c++/7/bits/random.h:1813:2: note:   passing ‘const std::uniform_real_distribution<long double>*’ as ‘this’ argument discards qualifiers
/usr/include/c++/7/bits/random.h:1818:2: note: candidate: template<class _UniformRandomNumberGenerator> std::uniform_real_distribution<_RealType>::result_type std::uniform_real_distribution<_RealType>::operator()(_UniformRandomNumberGenerator&, const std::uniform_real_distribution<_RealType>::param_type&) [with _UniformRandomNumberGenerator = _UniformRandomNumberGenerator; _RealType = long double]
  operator()(_UniformRandomNumberGenerator& __urng,
  ^~~~~~~~
/usr/include/c++/7/bits/random.h:1818:2: note:   template argument deduction/substitution failed:
montecarlo.cpp:728:41: note:   candidate expects 2 arguments, 1 provided
  for(auto rnd = urd(shared_random_engine); rnd >= 0; ++i) {
                                         ^

Так как последние строки ошибок говорят мне, что 2Ожидаются аргументы, я изменил код следующим образом:

for(auto rnd = urd(shared_random_engine, urd.param())

В Windows он по-прежнему работает нормально, но в Ubuntu я получаю эту ошибку, теперь говорю мне передать только 1 аргумент:

montecarlo.cpp: In member function ‘std::pair<std::weak_ptr<MonteCarloNode>, long unsigned int> NodeSelector::rouletteWheel() const’:
montecarlo.cpp:728:54: error: no match for call to ‘(const std::uniform_real_distribution<long double>) (std::minstd_rand&, std::uniform_real_distribution<long double>::param_type)’
  for(auto rnd = urd(shared_random_engine, urd.param()); rnd >= 0; ++i) {
                                                      ^
In file included from /usr/include/c++/7/random:49:0,
                 from selector.h:15,
                 from montecarlo.h:13,
                 from montecarlo.cpp:7:
/usr/include/c++/7/bits/random.h:1813:2: note: candidate: template<class _UniformRandomNumberGenerator> std::uniform_real_distribution<_RealType>::result_type std::uniform_real_distribution<_RealType>::operator()(_UniformRandomNumberGenerator&) [with _UniformRandomNumberGenerator = _UniformRandomNumberGenerator; _RealType = long double]
  operator()(_UniformRandomNumberGenerator& __urng)
  ^~~~~~~~
/usr/include/c++/7/bits/random.h:1813:2: note:   template argument deduction/substitution failed:
montecarlo.cpp:728:54: note:   candidate expects 1 argument, 2 provided
  for(auto rnd = urd(shared_random_engine, urd.param()); rnd >= 0; ++i) {
                                                      ^
In file included from /usr/include/c++/7/random:49:0,
                 from selector.h:15,
                 from montecarlo.h:13,
                 from montecarlo.cpp:7:
/usr/include/c++/7/bits/random.h:1818:2: note: candidate: std::uniform_real_distribution<_RealType>::result_type std::uniform_real_distribution<_RealType>::operator()(_UniformRandomNumberGenerator&, const std::uniform_real_distribution<_RealType>::param_type&) [with _UniformRandomNumberGenerator = std::linear_congruential_engine<long unsigned int, 48271, 0, 2147483647>; _RealType = long double; std::uniform_real_distribution<_RealType>::result_type = long double] <near match>
  operator()(_UniformRandomNumberGenerator& __urng,
  ^~~~~~~~
/usr/include/c++/7/bits/random.h:1818:2: note:   passing ‘const std::uniform_real_distribution<long double>*’ as ‘this’ argument discards qualifiers

Кто-нибудь знает, в чем здесь проблема?

1 Ответ

5 голосов
/ 20 марта 2019

std::uniform_real_distrubution::operator() не является константной функцией-членом, поэтому не может быть вызвано для постоянных экземпляров: [rand.dist.uni.real] .


Почему это работает в Windows? operator() от Microsoft, вероятно const, реализациям IIRC разрешено усиливать const спецификацию для функций-членов: http://eel.is/c++draft/member.functions#2.

...