2016-11-02 4 views
1

У меня есть класс, который создает объект для получения случайных чисел в определенном диапазоне, код выглядит следующим образомвызова неявно удаленные копии конструктор RandGenerator

#pragma once 

#include <random> 

class RandGenerator 
{ 
public: 
    RandGenerator(); 
    RandGenerator(const float& min, const float& max); 
    float nextRandom(); 

private: 
    std::random_device mRandDevice; 
    std::mt19937 mGenerator; 
    std::uniform_real_distribution<> mSampler; 
}; 

RandGenerator::RandGenerator() : RandGenerator(0.f, 1.f) 
{} 

RandGenerator::RandGenerator(const float& min, const float& max) 
{ 
    mGenerator = std::mt19937(mRandDevice()); 
    mSampler = std::uniform_real_distribution<>(min, max); 
} 

float RandGenerator::nextRandom() 
{ 
    return mSampler(mGenerator); 
} 

Затем я создал еще один класс, который имеет экземпляр RandGenerator для выборки из единичной сферы (довольно простой и наивной, но только для целей обучения), который выглядит как

#pragma once 

#include "randgenerator.h" 
#include "point.h" 

class UnitSphereSampler 
{ 
public: 
    UnitSphereSampler(); 
    Point nextSample(); 

private: 
    RandGenerator mRandGenerator; 
}; 

UnitSphereSampler::UnitSphereSampler() : 
mRandGenerator(RandGenerator(-1.f, 1.f)) // ERROR HERE 
{ 
} 

Point UnitSphereSampler::nextSample() 
{ 
    Point p; 

    do 
    { 
     float x = mRandGenerator.nextRandom(); 
     float y = mRandGenerator.nextRandom(); 
     float z = mRandGenerator.nextRandom(); 
     p = Point(x, y, z); 
    } while ((p - Point(0.f)).normSq() >= 1.f); 

    return p; 
} 

от того, что я могу видеть in this c++ reference объект std::random_device не имеет конструктор копирования, поэтому Я использую mRandGenerator(RandGenerator(-1.f, 1.f)) в конструкторе класса UnitSphereSampler.

Это работало отлично в VS2013, однако, я попытался собрать в OS X Sierra и получил ошибку

Call to implicitly-deleted copy constructor of RandGenerator

Я попытался точно указать место, где копия делается, но я не могу чтобы найти его, я искал правильную вещь или есть что-то еще, что мне не хватает? Я думал, что я инициализирую RandGenerator, избегая выполнения вызова конструктора копирования. Есть рекомендации?

ответ

0

Я думаю, что это имеет отношение к действительно с копией генерируется в строке mRandGenerator(RandGenerator(-1.f, 1.f))

Анализируя немного больше он создает RandGenerator RValue, который я считаю, будет вызывать конструктор перемещения неявно определенный компилятором, т.е. RandGenerator(const RandGenerator&& rg)

Теперь, даже заехав на перемещение конструктор RandGenerator, он должен копию объекта std::random_device, который не имеет, следовательно, дает ошибку.

Я только что понял это, но не уверен, я приглашаю более опытных людей, чтобы дать свои мысли и/или завершить этот ответ.

В то же время я буду использовать указатель на RandGenerator, что позволит избежать делать копию и компилировать безотказно, т.е.

UnitSphereSampler::UnitSphereSampler() 
{ 
    mRandGenerator = new RandGenerator(-1.f, 1.f); 
} 

mRandGenerator где имеет тип RandGenerator*.

Смежные вопросы