I have this pattern in my code:
public:
int start(const uint32_t channel);
int stop(const uint32_t channel);
void set_current_desc(uint32_t channel, uint64_t cdesc);
// ...
private:
const uint32_t channel_;
All functions take in the channel
argument. I would like to provide this interface:
public:
int start(const uint32_t channel);
int start(void) { return start(channel_); }
int stop(const uint32_t channel);
int stop(void) { return stop(channel_); }
void set_current_desc(uint32_t channel, uint64_t cdesc);
void set_current_desc(uint64_t cdesc) { set_current_desc(channel_, cdesc); }
// ...
private:
const uint32_t channel_;
Is there a general approach to doing this for all functions at once, or will I have to type it all out? I guess there exists some messy macro method but I would prefer a C++ non-macro solution.
Edit: The initial interface must remain due to backwards compatibility.
You can modify the methods to accept a std::optional
with a default value of std::nullopt
.
If the caller does not supply a channel (via the new interface) the channel_
member will be used.
If the caller supplies a channel (as you requested for backwards compatibility), it will be used.
This is done using the method std::optional::value_or
.
#include <optional>
#include <iostream>
#include <cstdint>
class Test {
public:
Test(uint32_t channel) : channel_(channel) {}
void start(std::optional<uint32_t> channel = std::nullopt)
{
// Determine `cur_channel` to use:
uint32_t cur_channel = channel.value_or(channel_);
// Use `cur_channel` ...
std::cout << "start, using channel: " << cur_channel << "\n";
}
private:
const uint32_t channel_;
};
int main() {
Test test{ 333 }; // `channel_` member will be 333
test.start(); // will use the `channel_` member of `test`
test.start(5); // will use 5 for the current channel (backwards compatibility)
}
Output:
start, using channel: 333
start, using channel: 5
A similar approach can be used for the rest of your methods.