C ++ get (), at () y tipos de variantes

1 、 estándar :: obtener (estándar :: intervalo)

plantilla < std :: size_t I, clase T, std :: size_t N>
constexpr T & get (std :: span <T, N> s) noexcept;

Span para obtener sel primer Ielemento de referencia.

La longitud del intervalo debe tener un valor estático (es decir, N! = Std :: dynamic_extent) y Idebe estar en un rango de [0, N)un valor entero. Esto se aplica en tiempo de compilación, a diferencia del operador [].

Parámetro s: la extensión del contenido a extraer

Devuelve: el sprimer Ielemento de referencia.

Complejidad: constante.

std :: obtener (std :: tupla)

Acceso de tupla a elementos especificados
(plantilla de función)

std :: get (std :: par)

(C ++ 11)

Acceder a pairun elemento
(plantilla de función)

std :: get (std :: variante)

(C ++ 17)

O un variantvalor de lectura de tipo de índice dado (si es un tipo único) , se lanza una excepción cuando se produce un error
std :: obtener (std :: matriz) Acceder a arrayun elemento
.........  

Caso:

#include <iostream>
#include <string>
#include <tuple>
#include <utility>
#include <array>
#include <variant>

int main()
{
    auto t = std::make_tuple(1, "Foo", 3.14);
    // 基于下标的访问
    std::cout << "(" << std::get<0>(t) << ", " << std::get<1>(t)
              << ", " << std::get<2>(t) << ")\n";
    // 基于类型的访问( C++14 起)
    std::cout << "(" << std::get<int>(t) << ", " << std::get<const char*>(t)
              << ", " << std::get<double>(t) << ")\n";
    // 注意: std::tie 和结构化绑定亦可用于分解 tuple

    auto p = std::make_pair(1, 3.14);
    std::cout << '(' << std::get<0>(p) << ", " << std::get<1>(p) << ")\n";
    std::cout << '(' << std::get<int>(p) << ", " << std::get<double>(p) << ")\n";

    std::array<int, 3> arr;
 
    // 设置值:
    std::get<0>(arr) = 1;
    std::get<1>(arr) = 2;
    std::get<2>(arr) = 3;
 
    // 获取值:
    std::cout << "(" << std::get<0>(arr) << ", " << std::get<1>(arr)
              << ", " << std::get<2>(arr) << ")\n";

    std::variant<int, float> v{12}, w;
    int i = std::get<int>(v);
    w = std::get<int>(v);
    w = std::get<0>(v); // 效果同前一行
 
    //  std::get<double>(v); // 错误: [int, float] 中无 double
    //  std::get<3>(v);      // 错误:合法的 index 值是 0 和 1
 
    try {
      std::get<float>(w); // w 含有 int ,非 float :将抛出异常
    }
    catch (std::bad_variant_access&) {} //错误时抛 std::bad_variant_access异常

    return 0;
}
输出:
(1, Foo, 3.14)
(1, Foo, 3.14)

(1, 3.14)
(1, 3.14)

(1, 2, 3)

2 、 en ()

std :: matriz <T, N> :: en

referencia en (size_type pos);

  (Hasta C ++ 17)

referencia constexpr en (size_type pos);

  (Desde C ++ 17)

const_reference en (tamaño_tipo pos) const;

  (Hasta C ++ 14)

constexpr const_reference en (size_type pos) const;

  (Desde C ++ 14)

Devuelve la ubicación especificada posen referencia al elemento, hay verificación de límites.

Parámetros: pos la posición del elemento a devolver

Valor de retorno: una referencia al elemento requerido.

Excepción:! Si (pos <size ()) que posno está dentro del alcance de la embarcación, se lanza el tipo de excepción std :: out_of_range .

        El tipo de contenedor C ++ sobrecarga el símbolo del operador []. El método at () tiene la misma función que el operador []. La diferencia es que el método introducido at () es más seguro que el operador [] para tomar elementos. El estándar C ++ no require operator [] para realizar El motivo de la verificación de subíndices fuera de límites es la eficiencia. Siempre forzar la verificación de subíndices fuera de límites aumentará la sobrecarga de rendimiento del programa. El método at () se proporciona para compensar esta función de verificación de acceso fuera de los límites. El uso del operador [] para recuperar elementos y el acceso fuera de los límites hará que el programa se bloquee. Puede informar directamente un error de segmentación y es difícil encontrar el código del problema, mientras que at () obtiene el elemento Exceeding the scope arrojará una excepción, que es fácil de detectar. En resumen, el método operator [] accede al elemento de manera eficiente, y at () accede al elemento de forma segura.

 

3 、 estándar :: variante

La plantilla de clase std::variantrepresenta un tipo de seguridad de la Commonwealth . std::variantUna instancia de retiene el valor de uno de sus tipos opcionales en cualquier momento, o no tiene valor en condiciones de error (este estado es difícil de lograr, consulte valueless_by_exception ).

Y comportamiento coherente de inicialización agregada de Commonwealth , si la variante retiene un Tvalor de tipo de objeto , directamente al variantobjeto representado por la Trepresentación de asignación del objeto. No permita variantasignar memoria adicional (dinámica).

variantNo se permite conservar referencias, matrices o tipos void. Aire varianttambién enfermedades de fórmula (Variante :: disponible STD < STD :: Monostate > en su lugar).

variant Se permite mantener el mismo tipo más de una vez, y es posible mantener diferentes versiones limitadas de cv del mismo tipo.

Con Commonwealth, el constructor predeterminado variantretiene su valor la primera opción, esa opción no está disponible a menos que la configuración predeterminada (variante ni puede constructor predeterminado en este caso: use la clase auxiliar std :: monostate hace que esta variantsea ​​la configuración predeterminada).

#include <variant>
#include <string>
#include <cassert>
 
int main()
{
    std::variant<int, float> v, w;
    v = 12; // v 含 int
    int i = std::get<int>(v);
    w = std::get<int>(v);
    w = std::get<0>(v); // 与前一行效果相同
    w = v; // 与前一行效果相同
 
//  std::get<double>(v); // 错误: [int, float] 中无 double
//  std::get<3>(v);      // 错误:合法下标值为 0 与 1
 
    try {
      std::get<float>(w); // w 含 int 而非 float :将抛出
    }
    catch (const std::bad_variant_access&) {}
 
    using namespace std::literals;
 
    std::variant<std::string> x("abc"); // 转换构造函数在无歧义时起作用
    x = "def"; // 转换赋值在无歧义时亦起作用
 
    std::variant<std::string, void const*> y("abc");
    // 传递 char const * 时转换成 void const *
    assert(std::holds_alternative<void const*>(y)); // 成功
    y = "xyz"s;
    assert(std::holds_alternative<std::string>(y)); // 成功
}

 

Supongo que te gusta

Origin blog.csdn.net/sunlin972913894/article/details/102983033
Recomendado
Clasificación