Q: Каковы основные правила, которые эффективно определяют: используется dist (rng) - я не понимаю, почему std :: bind будет обеспечивать это взаимодействие.Кажется, что многие взаимодействия основаны на методах operator ().
std::bind
выполняет составление функций .Первый аргумент должен быть объектом функции, то есть чем-то вызываемым , например, функцией (например, нормальной функцией или классом с перегруженным operator()
).
Вызов std::bind
создает копии своих аргументов, «привязывает» копии аргументов к первому аргументу (объекту функции) и возвращает новый объект функции, который будет вызывать копию функцииobject.
Таким образом, в простом случае:
int f(int i) { return i; }
auto f1 = std::bind(f, 1);
это связывает значение 1
с функцией f
, создавая новый объект функции, который можно вызывать без аргументов.Когда вы вызываете f1()
, он вызывает f
с аргументом 1
, то есть он вызывает f(1)
и возвращает все, что возвращает (что в данном случае просто 1
).
Фактический тип вещи, возвращаемой std::bind(f, 1)
, является неким типом класса, зависящим от реализации, который может называться как std::__detail::__bind_type<void(*)(int), int>
.Вы не должны ссылаться на этот тип напрямую, вы бы либо захватили объект с помощью auto
, либо сохранили бы его в другом месте, не обращающем внимания на точный тип, поэтому либо:
auto f1 = std::bind(f, 1);
или:
std::function<int()> f1 = std::bind(f, 1);
В более сложном случае, когда вы вызываете std::bind(decltype(p_dist){0, p - 1}, std::ref(rng)))
, вы получаете новый функциональный объект, который содержит копию временного decltype(p_dist){0, p - 1}
и копию reference_wrapper<std::mt19937>
, созданную std::ref(rng)
.Когда вы вызываете этот новый объект функции, он вызывает вызываемый дистрибутив, передавая ему ссылку на rng
.
Это означает, что он может вызываться без аргументов, и он будет вызывать распределение случайных чисел с содержимымслучайный механизм и возвращает результат.
Q: std::function
часто упоминается как «обертка полиморфной функции общего назначения» на cppreference.com.Так это функция, которая инкапсулирует тип возвращаемого значения uint64_t
?
A std::function<uint64_t()>
- это обертка для объекта функции, которая вызывается без аргументов и возвращает uint64_t
(или что-то в этом роде)неявно конвертируется в uint64_t
).Он может быть использован для хранения копии произвольного объекта функции, который может быть создан с возможностью копирования и без аргументов, и возвращает что-то, что можно преобразовать в uint64_t
.
(И, в общем, std::function<R(A1, A2 ... AN)>
- этооболочка для объекта функции, который возвращает R
при вызове с N аргументами типов A1
, A2
... AN
.)
, поскольку результатом вашего вызова std::bind
являетсяскопировать объект конструируемой функции, который вызывается без аргументов и возвращает uint64_t
, вы можете сохранить результат этого вызова std::bind
в std::function<uint64_t()>
, а когда вы вызываете function
, он вызовет результат bind
вызов, который вызовет содержащийся в нем дистрибутив и вернет результат.
Или снова, используя синтаксис operator () для определения понятия функции?
Я не уверен, что это значит, но в целом верно, что в C ++ мы часто говорим о «объектах функций» или «вызываемых объектах», которые являются обобщениями функций, то есть что-то, что может быть вызвано с помощью fuСинтаксис вызова nction, например a(b, c)