Notice: file_put_contents(): Write of 13531 bytes failed with errno=28 No space left on device in /var/www/tgoop/post.php on line 50
C++95@cxx95 P.62
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



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: |

The best encrypted messaging apps You can invite up to 200 people from your contacts to join your channel as the next step. Select the users you want to add and click “Invite.” You can skip this step altogether. With the sharp downturn in the crypto market, yelling has become a coping mechanism for many crypto traders. This screaming therapy became popular after the surge of Goblintown Ethereum NFTs at the end of May or early June. Here, holders made incoherent groaning sounds in late-night Twitter spaces. They also role-played as urine-loving Goblin creatures. Telegram channels enable users to broadcast messages to multiple users simultaneously. Like on social media, users need to subscribe to your channel to get access to your content published by one or more administrators. On Tuesday, some local media outlets included Sing Tao Daily cited sources as saying the Hong Kong government was considering restricting access to Telegram. Privacy Commissioner for Personal Data Ada Chung told to the Legislative Council on Monday that government officials, police and lawmakers remain the targets of “doxxing” despite a privacy law amendment last year that criminalised the malicious disclosure of personal information.
from us


Telegram C++95
FROM American