For the following Julia code:
mutable struct MutationWeights
mutate_constant::Float64
optimize::Float64
end
const mutations = [fieldnames(MutationWeights)...]
@generated function MutationWeights(;
mutate_constant=0.048,
optimize=0.0,
)
return :(MutationWeights($(mutations...)))
end
"""Convert MutationWeights to a vector."""
@generated function Base.convert(
::Type{Vector}, weightings::MutationWeights
)::Vector{Float64}
fields = [:(weightings.$(mut)) for mut in mutations]
return :([$(fields...)])
end
I wrote the following C++ alternative:
struct MutationWeights {
float mutate_constant = 0.048;
float optimize = 0.0;
};
const auto mutations = std::vector<std::string>{"mutate_constant", "optimize"};
template <typename... Args>
MutationWeights createMutationWeights(Args&&... args) {
return {std::forward<Args>(args)...};
}
std::vector<double> convertMutationWeightsToVector(const MutationWeights& weightings) {
return {weightings.mutate_constant,
weightings.optimize};
}
Is this the most sensible way of doing it, or would you suggest something different?
-
1\$\begingroup\$ Hope my edit describes what your code is doing. \$\endgroup\$convert– convert2023年06月25日 16:13:08 +00:00Commented Jun 25, 2023 at 16:13
1 Answer 1
Precision
float
is usually a 32-bit floating point type. Perhaps you meant double
? With C++23, you can use std::float64_t
.
Aggregates
There is aggregate initialization that removes the need for createMutationWeights
. Note that if narrowing conversion should be allowed, then createMutationWeights
does not help with it.
(Implicit) conversion functions
If the conversion into std::vector<double>
is often needed, I would implement a conversion function and make it explicit
(will require a cast like static_cast
to be used) if needed.
struct MutationWeights {
float mutate_constant = 0.048;
float optimize = 0.0;
operator std::vector<double>() {
return { mutate_constant, optimize };
}
};
Reconsider the interface
I would recommend returning std::span<float>
or even std::span<float, 2>
(i.e. statically sized). One could also try std::array<float, 2>
to avoid some lifetime issues.
-
\$\begingroup\$ Not that important but maybe you want to remove
weightings
from your vector implementation. \$\endgroup\$dearn44– dearn442023年06月24日 17:57:09 +00:00Commented Jun 24, 2023 at 17:57