Daily bit(e) C++. Условный оператор

Добавлено 4 августа 2023 в 02:17

Daily bit(e) C++ #3, Условный (он же тернарный) оператор.

Daily bit(e) C++. Условный оператор

Условный оператор, также известный как тернарный оператор, по сути, является инструкцией if в виде выражения.

Этот оператор последовательный. Сначала вычисляется левая часть со всеми ее побочными эффектами, а затем один из правых операндов (в зависимости от логического значения первого операнда).

Если типы двух правых аргументов различаются, можно применить преобразования для получения совместимого общего типа, результирующего типа выражения.

До того, как C++17 представил if constexpr, тернарный оператор также был основным способом внедрения логики в выражение constexpr.

#include <string>
#include <memory>
#include <stdexcept>
#include <array>
#include <iostream>

struct A {};
struct B : A {};

struct MustBeInit 
{
    MustBeInit(int v) : v(v) {}
    int v;
};

int main() 
{
    // простая арифметическая логика:
    int x = 1;
    int y = 2;
    int abs_diff = x < y ? y - x : x - y;

    // Полезно для инициализации переменных,
    // которые не поддерживают инициализацию по умолчанию:
    MustBeInit m = true ? 1 : 2;

    // До C++17 условный оператор был основным
    // способом внедрения логики в код constexpr.
    constexpr bool has_many = true;
    std::array<int, has_many ? 1024 : 8> arr;

    // При смешивании типов разрешены стандартные
    // преобразования, например:
    static_assert(std::is_same_v< // int->double
        decltype(true ? 2.0 : 1), double        
    >);
    static_assert(std::is_same_v< // производный класс в базовый
        decltype(true ? A() : B()), A
    >);

    // Выражения throw разрешены, так как они прерывают поток:
    auto ptr = std::make_unique<std::string>("abc");
    size_t len = ptr ? ptr->length() : 
        throw std::runtime_error("Null pointer dereference.");

    // Если обе стороны являются выражениями throw,
    // результат будет void.
    static_assert(std::is_same_v<
        decltype(true ? throw 1 : throw 2), void
    >);

    // При смешивании cv-квалификаторов (const/volatile)
    // аргументы должны перекрываться, но в результате
    // получается наиболее квалифицированный тип.
    int a = 1;
    const int& b = 2;
    int& c = a;
    static_assert(std::is_same_v<
        decltype(true ? b : c), const int&
    >);
}

Открыть пример на Compiler Explorer.

Теги

C++ / CppDaily bit(e) C++Программирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.