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 s
el primer I
elemento de referencia.
La longitud del intervalo debe tener un valor estático (es decir, N! = Std :: dynamic_extent) y I
debe 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 s
primer I
elemento de referencia.
Complejidad: constante.
Acceso de tupla a elementos especificados (plantilla de función) |
|
(C ++ 11) |
Acceder a pair un elemento (plantilla de función) |
(C ++ 17) |
O un variant valor 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 array un 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 pos
en 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 pos
no 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::variant
representa un tipo de seguridad de la Commonwealth . std::variant
Una 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 T
valor de tipo de objeto , directamente al variant
objeto representado por la T
representación de asignación del objeto. No permita variant
asignar memoria adicional (dinámica).
variant
No se permite conservar referencias, matrices o tipos void
. Aire variant
tambié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 variant
retiene 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 variant
sea 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)); // 成功
}