EV0R
EV0R

Reputation: 33

Multiton pattern in C++ failed with C2676 under MSVC Compiler

I am writing a mutiton pattern class in C++, but run into C2676 with MSVC compiler.

C2676 :
binary '<' : 'type*' does not define this operator or a conversion to a type acceptable to the predefined operator.

Here is my code:

#include <iostream>
#include <map>

struct Person
{
    uint16_t height;  // in mm
    uint16_t weight;  // in kg
};

using PersonId    = std::uint16_t;
using PersonTable = std::map<PersonId, Person>;

PersonTable persons = {
    {1, { 1720, 70 }},
    {2, { 1800, 80 }},
    {3, { 1720, 70 }},
    {4, { 1900, 90 }},
};

// Body Mass Index
class BMI
{
public:
    BMI(const Person& person)
        : m_Person(person)
    {
    }

    ~BMI() {}

public:
    float calc()
    {
        auto bmi = (m_Person.weight / 1000)
                 / ((m_Person.height / 1000) * (m_Person.height / 1000));
        std::cout << "this is : " << this << "\t"
                  << "BMI : " << bmi << std::endl;
        return bmi;
    }

private:
    Person m_Person;
};

class Multiton
{
public:
    static std::shared_ptr<BMI> getInstance(const Person& person)
    {
        // try to find key
        std::map<Person, std::shared_ptr<BMI>>::iterator iter
            = m_Instances.find(person);

        if (iter != m_Instances.end())  // if found
        {
            return iter->second;
        }
        else  // if not found
        {
            auto ptrObj         = std::make_shared<BMI>(person);
            m_Instances[person] = ptrObj;
            return ptrObj;
        }
    }

private:
    static std::map<Person, std::shared_ptr<BMI>> m_Instances;
};

// Initialization
std::map<Person, std::shared_ptr<BMI>> Multiton::m_Instances = {};

int main(int argc, const char* argv[])
{
    auto ptrBmi01 = Multiton::getInstance(persons[1]);
    ptrBmi01->calc();

    auto ptrBmi02 = Multiton::getInstance(persons[2]);
    ptrBmi02->calc();

    auto ptrBmi03 = Multiton::getInstance(persons[3]);
    ptrBmi03->calc();

    auto ptrBmi04 = Multiton::getInstance(persons[4]);
    ptrBmi04->calc();

    return 0;
}

I checked Microsoft Learn and some relevant stackoverflow page and some spend some time to debug it, but i still have no clue.

I just want to use multiton to create BMI object with BMI::BMI(const Person& person).

Any advice is greatly appreciated.

Upvotes: 1

Views: 68

Answers (1)

john
john

Reputation: 87957

std::map is an ordered container. Therefore given std::map<Person, std::shared_ptr<BMI>> the compiler must know how to order Person.

The error message you are seeing is because there is no operator< defined for Person and therefore the compiler does not know how to order the people in your map.

The simple solution is to define a suitable

bool operator<(const Person& x, const Person& y);

Upvotes: 1

Related Questions