std::variant (Manual Virtual Dispatch, Using if)

Overview

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;
}