std::variant
(Manual Virtual Dispatch, Using if
)¶
Overview¶
Take
union
approach from Unrelated (Duck-Typed) further⟶ store not only pointers, but objects
Manual virtual dispatch (see
code/variant-manual-if/virtual.h
) based onstd::variant<>
examination (if
)⟶ Adding another sensor type requires another branch in
if
Sensor Definitions¶
#pragma once
#include <variant>
class Sensor1
{
public:
Sensor1(double temperature) : _temperature{temperature} {}
double get_temperature() { return _temperature; }
Sensor1() = delete;
Sensor1(const Sensor1&) = delete;
Sensor1& operator=(const Sensor1&) = delete;
Sensor1(Sensor1&&) = default;
Sensor1& operator=(Sensor1&&) = default;
private:
double _temperature;
};
class Sensor2
{
public:
Sensor2(double temperature) : _temperature{temperature} {}
double get_temperature() { return _temperature; }
Sensor2() = delete;
Sensor2(const Sensor2&) = delete;
Sensor2& operator=(const Sensor2&) = delete;
Sensor2(Sensor2&&) = default;
Sensor2& operator=(Sensor2&&) = default;
private:
double _temperature;
};
using Sensor = std::variant<Sensor1, Sensor2>;
Virtual Access¶
#pragma once
static inline double get_temperature(Sensor& s)
{
if (Sensor1* s1 = std::get_if<Sensor1>(&s))
return s1->get_temperature();
if (Sensor2* s1 = std::get_if<Sensor2>(&s))
return s1->get_temperature();
return -273.15; // <--- take care to never get here
}
Average Across Many¶
#pragma once
#include "virtual.h"
double average(auto& sensors) // <--- abbreviated function template
{
double sum = 0;
unsigned long num = 0;
for (auto& s: sensors) {
++num;
sum += get_temperature(s);
}
return sum/num;
}
Main Program¶
#include "sensors.h"
#include "avg.h"
#include <iostream>
int main()
{
Sensor sensors[] = {Sensor1{42.1}, Sensor2{37.5}};
std::cout << average(sensors) << std::endl;
return 0;
}