В студии давно появился флаг "/std:c++17" и недавно "/std:c++20", о котором я расскажу в следующей статье, каждый из этих стандартов привнес много новшеств в язык и стандартную библиотеку, которыми не все пользуются, особенно при создании малвари, потому что они тянут исключения, CRT.
Однако есть полезные и удобные фичи, которые позволяют быстрее и удобнее писать многие вещи и они не тянут исключения и CRT.
Оглавление:
1. constexpr
Constexpr был добавлен еще в C++11 и все его знают благодаря xorstr и другим библиотекам, которые позволяют в compile-time хоть как-то обфусцировать строки, однако теперь можно писать if constexpr (expression) чтобы использовать условные операторы в compile-time.
if constexpr можно использовать в compile-time алгоритмах, а также при проверках типов, например так:
В этой статье я привел примеры compile-time crc32, вычисления чисел фибоначчи и как можно работать со string_view.
Была добавлена возможность использовать constexpr лямбда-функции, если они удовлетворяют требованиям constexpr функций.
2. string_view
Данный контейнер является constexpr и не тянет за собой CRT, но может, если хотите перестраховаться, то нужно брать чужую реализацию, либо писать свою на основе чужой, благо исходного кода STL предостаточно.
Данный контейнер не владеет строкой, а принимает char-образные данные, обычно хранит только указатель на начало строки и размер.
Плюсом является доступ к таким функциям-членам как: operator[](), at(), front(), back(), data(), size(), empty(), swap(), substr(), compare(), find(), rfind(), все из которых constexpr.
3. Structure binding
Очень простая и удобная фича, которая позволяет писать более читаемый код:
4. Deduction guides
В большинстве случаев они генерируются неявно и позволяют писать следующий код:
Однако можно писать и собственные deduction guides для создания объектов, например:
Данный код делает так, чтобы MyPair(543.5f, "string") хранилась как MyPair<float, std::string_view>(543.5f, "string"), а не как MyPair<float, const char*>(543.5f, "string").
5. Fold Expressions
Позволяет использовать следующие операции с паками параметров:
Это лишь малая часть нововведений в С++17, однако именно их можно использовать при написании софта, если вам требуется отключить SDL, exceptions, CRT и прочий мусор.
Однако есть полезные и удобные фичи, которые позволяют быстрее и удобнее писать многие вещи и они не тянут исключения и CRT.
Оглавление:
- constexpr
- string_view
- Structure binding
- Deduction guides
- Fold Expressions
1. constexpr
Constexpr был добавлен еще в C++11 и все его знают благодаря xorstr и другим библиотекам, которые позволяют в compile-time хоть как-то обфусцировать строки, однако теперь можно писать if constexpr (expression) чтобы использовать условные операторы в compile-time.
if constexpr можно использовать в compile-time алгоритмах, а также при проверках типов, например так:
C++:
template <typename T>
constexpr auto GetPointer(const T& t) {
if constexpr (std::is_pointer_v<T>) // std::is_pointer_v<T> - compile-time функция и не тянет CRT, находится в <type_traits>
return t;
else
return &t;
}
В этой статье я привел примеры compile-time crc32, вычисления чисел фибоначчи и как можно работать со string_view.
Была добавлена возможность использовать constexpr лямбда-функции, если они удовлетворяют требованиям constexpr функций.
C++:
int main(int argc, char* argv[])
{
constexpr auto Kylobytes = [](int n) -> int {
return n * 1024;
};
constexpr auto kb_1024 = Kylobytes(1024);
return kb_1024;
}
2. string_view
Данный контейнер является constexpr и не тянет за собой CRT, но может, если хотите перестраховаться, то нужно брать чужую реализацию, либо писать свою на основе чужой, благо исходного кода STL предостаточно.
Данный контейнер не владеет строкой, а принимает char-образные данные, обычно хранит только указатель на начало строки и размер.
Плюсом является доступ к таким функциям-членам как: operator[](), at(), front(), back(), data(), size(), empty(), swap(), substr(), compare(), find(), rfind(), все из которых constexpr.
C++:
int main(int argc, char* argv[])
{
using namespace std::literals;
auto temp_str_view = "some data yopta"sv; // литерал 'sv' находящийся в std::literals позволяет писать так, иначе всегда будет необходимо явно указывать тип переменной как std::string_view
if (!temp_str_view.empty())
return temp_str_view[7];
return -1;
}
3. Structure binding
Очень простая и удобная фича, которая позволяет писать более читаемый код:
C++:
typedef struct {
std::string_view name;
int age;
float balance_rub;
float balance_btc;
void* optional;
size_t szOptional;
} UserInfo;
UserInfo GetUserDataFromAnywhere(size_t uid = 1)
{
// searching user...
return {"Kojima", 45, 0.f, 152.25f, nullptr, 0};
}
int main(int argc, char* argv[])
{
auto [name, age, nRub, nBtc, opt, szOpt] = GetUserDataFromAnywhere(); // structure binding
// Теперь мы можем использовать имена name, age и другие
// Важно использовать все поля структуры, иначе будет ошибка компиляции
return age;
}
4. Deduction guides
В большинстве случаев они генерируются неявно и позволяют писать следующий код:
C++:
template <typename T1, typename T2>
struct MyPair {
T1 first;
T2 second;
MyPair(const T1& t1, const T2& t2) {
first = t1;
second = t2;
}
~MyPair() = default;
};
int main(int argc, char* argv[])
{
auto p1 = MyPair(543.5f, "string"sv); // C++17, в С++14 пришлось бы написать MyPair<float, const char*>(...)
}
Однако можно писать и собственные deduction guides для создания объектов, например:
C++:
template <typename T1>
MyPair(T1, const char*) -> MyPair<T1, std::string_view>;
template <typename T2>
MyPair(const char*, T2) -> MyPair<std::string_view, T2>;
5. Fold Expressions
Позволяет использовать следующие операции с паками параметров:
+ - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->*
C++:
template<typename... Args>
constexpr int sum(Args&&... args) {
return (args + ... );
}
template<typename... Args>
constexpr bool isEverythingGood(Args&&... args) {
return (... && args);
}
int main(int argc, char* argv[])
{
constexpr int summa = sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
constexpr bool isGood = isEverythingGood(true, true, false, true, true, true);
return isGood;
}
Это лишь малая часть нововведений в С++17, однако именно их можно использовать при написании софта, если вам требуется отключить SDL, exceptions, CRT и прочий мусор.