Giter Site home page Giter Site logo

Better-enum in maps about better-enums HOT 7 OPEN

biziosan avatar biziosan commented on June 12, 2024
Better-enum in maps

from better-enums.

Comments (7)

jaskij avatar jaskij commented on June 12, 2024 1

Use emplace

BETTER_ENUM(encodings_e, int,
    RED,
    GREEN,
    BLUE
)

std::unordered_map<std::string, encodings_e> map;

map.emplace(std::make_pair("rr", encodings_e::RED);
encodings_e foo = map["rr"];
std::cout << foo._to_string() << std::endl;

Edit:

@aantron come to think of it, I believe emplace is the only way to avoid using a default-constructed temporary when inserting into standard containers, maybe you could add that info to documentation?

from better-enums.

aantron avatar aantron commented on June 12, 2024

It's been a long time, but it looks like there is an intermediate call to a default constructor somewhere during the insert.

I'm not immediately sure what the best solution to this is, but you should be able to work around it in at least one way by declaring the constructor public as desribed here: https://aantron.github.io/better-enums/OptInFeatures.html#DefaultConstructors.

from better-enums.

aantron avatar aantron commented on June 12, 2024

@jaskij Thanks!

Let's see if there is any word from @biziosan on whether emplace fixes the issue, and then I'll add it to the docs.

from better-enums.

jaskij avatar jaskij commented on June 12, 2024

@aantron since I'm dealing with Better Enums now anyway I've tested this, also using gcc 9.3.

TL;DR: operator[] for std::map and std::unordered_map requires the value type to be default constructible.

The result is that std::unordered_map::operator[] (and likely std::map::operator[] too) won't work. The reason is that operator[] looks up the key and inserts a default-constructed value if the key is not present in the map. Even if we don't use it that way the compiler can't instantiate the operator if the value type is not default constrible.

Also, consider the following notes from operator[] description on cppreference.com:

In the published C++11 and C++14 standards, this function was specified to require mapped_type to be DefaultInsertable and key_type to be CopyInsertable or MoveInsertable into *this. This specification was defective and was fixed by LWG issue 2469, and the description above incorporates the resolution of that issue.

However, one implementation (libc++) is known to construct the key_type and mapped_type objects via two separate allocator construct() calls, as arguably required by the standards as published, rather than emplacing a value_type object.

operator[] is non-const because it inserts the key if it doesn't exist. If this behavior is undesirable or if the container is const, at() may be used.

All in all, insert via emplace() and access via at(), those are sure to work.

Sample code:

#include <iostream>
#include <map>

#include <better-enums/enum.h>

BETTER_ENUM(mbool, char, mfalse = 0, mtrue = 1)

int main() {
    std::map<std::string, mbool> map;
    map.emplace(std::make_pair("true", mbool::mfalse));
    //const auto t = map["true"]; // compiler error
    const auto t = map.at("true");
    //std::cout << map["true"] << std::endl; // compiler error
    std::cout << map.at("true") << std::endl;
    std::cout << t << std::endl;

    return 0;
}

from better-enums.

biziosan avatar biziosan commented on June 12, 2024

I haven't tried emplace() yet, but with the default constructor enabled my simple code works. I'll test emplace() right away as well.

from better-enums.

jaskij avatar jaskij commented on June 12, 2024

@biziosan I don't know if you read my last message, but regardless of emplace(), without a public default constructor you can't use operator[] with maps, so that might be a pain point.

from better-enums.

biziosan avatar biziosan commented on June 12, 2024

@jaskij Hi, yes, thank you! It matches with I have working. I used @aantron suggestion about public default constructors and enabled them (https://aantron.github.io/better-enums/OptInFeatures.html#DefaultConstructors). That worked right away!

I think I am satisfied with the answers. I can close this issue if you want.

from better-enums.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.