2
\$\begingroup\$

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?

asked Jun 24, 2023 at 2:41
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Hope my edit describes what your code is doing. \$\endgroup\$ Commented Jun 25, 2023 at 16:13

1 Answer 1

6
\$\begingroup\$

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.

Toby Speight
87.1k14 gold badges104 silver badges322 bronze badges
answered Jun 24, 2023 at 13:06
\$\endgroup\$
1
  • \$\begingroup\$ Not that important but maybe you want to remove weightings from your vector implementation. \$\endgroup\$ Commented Jun 24, 2023 at 17:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.