Как поместить различные шаблонные типы в один вектор

Ну, вы можете сделать свою собственную функцию, но остерегайтесь следующего. Каждое число должно быть нарисовано с равной вероятностью. Вам нужно будет определить, из какого диапазона будет получено число с вероятностью, пропорциональной размеру диапазона, например, Рисование из [1,10], [21, 40] должно составлять числа из [21,40] примерно в два раза чаще, чем из [1,10].

Вот общая идея:

Определить длину всех диапазонов.

Нарисуйте случайное число от 0 до длины всех диапазонов.

Проверьте, к какому диапазону относится число.

Нарисуйте соответствующее число из диапазона, в котором оно находится.

 function randFromRanges(...$ranges) {
       $totalRangeSize = array_sum(array_map(function ($range) { 
             return $range[1] - $range[0];
       }, $ranges));
       $numberToDraw = rand(0, $totalRangeSize);
       foreach ($ranges as $range) {
            if ($numberToDraw <=  ($range[1] - $range[0])) {
                return $range[0]+$numberToDraw;
            } else {
               $numberToDraw -= ($range[1] - $range[0]);
            }
       }
   }

Вот песочница, которая показывает, что все значения кажутся равноправными:

http://sandbox.onlinephpfunctions.com/code/b02603e4a9986132073d203c98f8255c2dd62e47

9
задан DaClown 30 March 2009 в 08:26
поделиться

3 ответа

Опция 1: удостоверьтесь, что все различные типы аргументов происходят из базового класса и используют указатели на тот класс. Обратите внимание, что эта опция опасна с точки зрения управления памятью. Вы могли бы хотеть сделать это более безопасным при помощи повышения:: shared_ptr вместо указателей. Иначе необходимо вручную вымыться, когда объект удаляется из вектора.

Опция 2 (мой любимый): используйте Повышение. Вариант, чтобы сделать определение типа всех возможных типов аргумента и использовать то определение типа в качестве типа аргумента в станд.:: вектор

typedef boost::variant<ArgumentType1, ArgumentType2, ArgumentType3> ArgumentType;
std::vector<ArgumentType> vec;
14
ответ дан 4 December 2019 в 08:34
поделиться

Вы могли использовать повышение:: вариант (http://www.boost.org/doc/libs/1_38_0/doc/html/variant.html)
или повышение:: любой (http://www.boost.org/doc/libs/1_38_0/doc/html/any.html) типы

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

Но я не уверен, что использование подобных типов является хорошим дизайном.

5
ответ дан 4 December 2019 в 08:34
поделиться

Самый легкий способ сделать это должно было бы иметь основной класс Аргумента, который не является шаблонным, и затем имейте определенные типы данных, происходят из него. (Вы могли даже заставить шаблонную версию произойти из базового класса непосредственно и просто использовать те два класса.) Затем Вы храните их как указатели в векторе.

Это действительно требует, чтобы наличие своего рода функций получило доступ к значениям аргументов и выполнило любые преобразования как требуется.

6
ответ дан 4 December 2019 в 08:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: