This is a follow up to this question so if you need to see the Register class please refer to that question. Now based on the supplied answer I have written a function to do just that. I have 2 versions of the function one that will store the results back into the original and one that will return a copy. Here are my functions:
template<std::uint64_t N>
void reverseBitOrder( Register<N>& reg ) {
auto str = reg.register_.to_string();
std::reverse(str.begin(), str.end());
auto x = vpc::Byte(str);
reg.register_ = x;
}
// Extra unused parameter to avoid ambiguity
template<std::uint64_t N>
Register<N> reverseBitOrder(Register<N>& reg, bool _x_ /*not used*/ ) {
auto str = reg.register_.to_string();
std::reverse(str.begin(), str.end());
auto x = vpc::Byte(str);
Register<N> temp;
temp.register_ = x;
return temp;
}
The first one saves the value, the second returns a copy. My question is on the 2nd function I ended up adding a second parameter that is not used in order to avoid ambiguity due to overload resolution as functions can not be resolved on return types alone. So when I call this function I would have to pass either 0
, 1
, true
or false
to the function which has no effect.
Overall this in itself is not a very big deal, however, it doesn't seem very clean and concise to me. Are there any other ways to achieve this? I prefer not to make this a function of the class. My Register class or struct is complete as is and any kind of operations done on a register will be done by functions that take a reference to one or more register objects.
You can use
std::optional
to achieve this.The
return
type of function templatereverseBitOrder
should bestd::optional<vpc::Register<N>>
.The function template should be modified to:
Live Demo here
.But you don't really need to use
std::optional
, since there is really no "failure" case in the function template.If I understand correctly, both functions compute
x
and store it in aRegister<N>
, but one returns said object by value while the other stores the result in the function's argumentreg
.Technically, this can be done by overloading on constness by defining those two functions:
While this technically answers your question, that would be terrible design. If I'm not mistaken, the real issue is that what you want is this:
The problem with this is that whether the returned value is used or not is not something you can detect from inside the function.
The proper way to have one function do two things here would be to have a function with this signature:
That function would use
inputReg
to computex
then store the result inoutputReg
, meaning you would use it like this:Now, if that really doesn't do it for you, there is a way to get the syntaxic sugar you're looking for, at the cost of unneeded complexity and of adding a constructor to
Register<N>
. It would look roughly like this:That allows you to do
I can't recommend doing that though, it's more trouble than it's worth. I suggest using the solution I called "the proper way". It the least complicated and the one which is the hardest to use wrong later