CXX95 Telegram 62
#madskillz

Простой switch для строк 🎲

В C++ в switch-выражении в case не могут находиться строки или строковые литералы.

Там могут быть только константные значения целочисленного типа или значения enum-ов (а enum это и есть целочисленный тип под прикрытием).

Такое жесткое ограничение сделано из практических соображений - switch-выражения в бинарнике могут трансформироваться в супер-оптимизированный вид с помощью branch table, когда по целочисленному значению аргумента просто вычисляется адрес кода, куда надо прыгнуть.

Понятно, что для строк branch table сделать нельзя, и эффективность switch-а не будет отличаться от кучи if-ов.

В других языках строки в switch возможны - Java 7, C# 6, но там нет упора на максимальную производительность.

Но можно сделать самописный простой "switch", чтобы упростить такой код:
    Color color = UnknownColor;
if (argv[i] == "red") {
color = Red;
} else if (argv[i] == "orange") {
color = Orange;
} else if (argv[i] == "yellow") {
color = Yellow;
} else if (argv[i] == "green") {
color = Green;
} else if (argv[i] == "violet" || argv[i] == "purple") {
color = Violet;
}
В такой:
    Color color = StringSwitch<Color>(argv[i])
.Case("red", Red)
.Case("orange", Orange)
.Case("yellow", Yellow)
.Case("green", Green)
.Cases("violet", "purple", Violet)
.Default(UnknownColor);

Реализация StringSwitch есть в llvm: StringSwitch.h

Внутри этого класса всего два поля:
1️⃣ std::string_view str - сравниваемая строка (в нашем примере argv[i])
2️⃣ std::optional<T> value - итоговое значение (в нашем случае T = Color)

При вызове метода Case, если value еще не заполнено и строка равна нужной, то value заполняется.
Есть методы EndsWith и StartsWith, которые заполнят value, если часть строки равна нужной.
Есть аналогичные case-insensitive методы, а также методы Cases для нескольких значений.
Наконец есть оператор приведения к нужному типу (в нашем случае к Color).

На мой взгляд, можно еще сделать класс LambdaSwitch, который в отличие от StringSwitch мог бы принимать лямбды, и ставить значение, если лямбда возвращает true. 😐
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8



tgoop.com/cxx95/62
Create:
Last Update:

#madskillz

Простой switch для строк 🎲

В C++ в switch-выражении в case не могут находиться строки или строковые литералы.

Там могут быть только константные значения целочисленного типа или значения enum-ов (а enum это и есть целочисленный тип под прикрытием).

Такое жесткое ограничение сделано из практических соображений - switch-выражения в бинарнике могут трансформироваться в супер-оптимизированный вид с помощью branch table, когда по целочисленному значению аргумента просто вычисляется адрес кода, куда надо прыгнуть.

Понятно, что для строк branch table сделать нельзя, и эффективность switch-а не будет отличаться от кучи if-ов.

В других языках строки в switch возможны - Java 7, C# 6, но там нет упора на максимальную производительность.

Но можно сделать самописный простой "switch", чтобы упростить такой код:

    Color color = UnknownColor;
if (argv[i] == "red") {
color = Red;
} else if (argv[i] == "orange") {
color = Orange;
} else if (argv[i] == "yellow") {
color = Yellow;
} else if (argv[i] == "green") {
color = Green;
} else if (argv[i] == "violet" || argv[i] == "purple") {
color = Violet;
}
В такой:
    Color color = StringSwitch<Color>(argv[i])
.Case("red", Red)
.Case("orange", Orange)
.Case("yellow", Yellow)
.Case("green", Green)
.Cases("violet", "purple", Violet)
.Default(UnknownColor);

Реализация StringSwitch есть в llvm: StringSwitch.h

Внутри этого класса всего два поля:
1️⃣ std::string_view str - сравниваемая строка (в нашем примере argv[i])
2️⃣ std::optional<T> value - итоговое значение (в нашем случае T = Color)

При вызове метода Case, если value еще не заполнено и строка равна нужной, то value заполняется.
Есть методы EndsWith и StartsWith, которые заполнят value, если часть строки равна нужной.
Есть аналогичные case-insensitive методы, а также методы Cases для нескольких значений.
Наконец есть оператор приведения к нужному типу (в нашем случае к Color).

На мой взгляд, можно еще сделать класс LambdaSwitch, который в отличие от StringSwitch мог бы принимать лямбды, и ставить значение, если лямбда возвращает true. 😐

BY C++95


Share with your friend now:
tgoop.com/cxx95/62

View MORE
Open in Telegram


Telegram News

Date: |

Earlier, crypto enthusiasts had created a self-described “meme app” dubbed “gm” app wherein users would greet each other with “gm” or “good morning” messages. However, in September 2021, the gm app was down after a hacker reportedly gained access to the user data. Clear Matt Hussey, editorial director at NEAR Protocol also responded to this news with “#meIRL”. Just as you search “Bear Market Screaming” in Telegram, you will see a Pepe frog yelling as the group’s featured image. The Channel name and bio must be no more than 255 characters long Judge Hui described Ng as inciting others to “commit a massacre” with three posts teaching people to make “toxic chlorine gas bombs,” target police stations, police quarters and the city’s metro stations. This offence was “rather serious,” the court said.
from us


Telegram C++95
FROM American