Reputation: 123
I would like to implement a class design that achieves the following architecture:
I would like to instantiate classes that describe the object "ReadoutChip" of 4 different flavours, defined by the enumeration:
enum Flavour {F1, F2, F3, F4};
so that a class of a given flavour can be achieved like:
ReadoutChip<F1> Chip_1;
I have to specialize in some features of these flavour instantiations while keeping others the same. For example, all Chip objects (of all flavours) should have a private variable called Threshold
; and I would like to have common public methods like GetThreshold()
. However, these different flavours should have different attributes, which requires template specification. I have been unsuccessful in implementing something like this. Below is my attempt so far:
#include <iostream>
enum Flavour {F1, F2, F3, F4};
template <Flavour E, bool base = true> class ReadoutChip
{
private:
double Threshold = 1000;
public:
double GetThreshold();
};
template <> class ReadoutChip<Flavour::F1, true> : public ReadoutChip<Flavour::F1, false>
{
public:
ReadoutChip();
~ReadoutChip() = default;
void SayHi();
};
ReadoutChip<Flavour::F1, true>::ReadoutChip() {std::cout << "Hi!" << std::endl;}
template <> double ReadoutChip<Flavour::F1, false>::GetThreshold() {return this->Threshold;}
int main()
{
ReadoutChip<Flavour::F1> F_1;
std::cout << F_1.GetThreshold() << std::endl;
return 0;
}
This compiles successfully and somewhat gets the job done. Its only problems are that I have to copy the line:
template <> double ReadoutChip<Flavour::F1, false>::GetThreshold() {return this->Threshold;}
for each flavour, and apparently the line,
template <Flavour E> double ReadoutChip<E, true>::GetThreshold() {return this->Threshold;}
outputs a compilation error. Despite the partial success of this implementation, I would like to know if there is a way to achieve such a result without using the boolean variable base here, for the sake of C++ rigour.
Upvotes: 1
Views: 44
Reputation: 5503
If I've understood the question correctly I think a better fit here would be inheritance.
Have all of your "chip" variants derive from a common base class
.
Stick all of your common code in the base class
.
Take the example below, you can create as many "chip" variants as you'd like, just have them derive from your base class
.
class readout_chip_base
{
public:
readout_chip_base(double threshold) noexcept
: threshold_{threshold}
{}
double get_threshold() const noexcept {
return threshold_;
}
virtual void take_reading() = 0;
virtual ~readout_chip_base() = default;
protected:
void update_threshold(double threshold) noexcept {
threshold_ = threshold;
}
private:
double threshold_;
};
class f1_readout_chip : public readout_chip_base
{
public:
f1_readout_chip() noexcept
: readout_chip_base{42.01}
{}
void take_reading() override {
update_threshold(104.23);
}
};
int main()
{
f1_readout_chip f1{};
std::cout << f1.get_threshold() << '\n';
f1.take_reading();
std::cout << f1.get_threshold() << '\n';
}
Upvotes: 1