C ++: tupla 55 --- la naturaleza especial de la biblioteca estándar de instalación

A, tupla general

  • tupla y un par similar, sino también una plantilla . par lleva dos miembros, tupla para aceptar cualquier número de miembros
  • Cuando queremos combinar algunos datos en un solo objeto, tupla útil
  • La siguiente es una tupla operaciones de apoyo, se definen en el archivo de cabecera en tupla:

En segundo lugar, la definición e inicialización tupla

  • Cuando se define una tupla, que debería ser de tipo conocido de cada miembro:
std::tuple<size_t, size_t, size_t> threeD; //使用默认构造函数

std::tuple<std::string, std::vector<double>, int, std::list<int>>
    someVal("constants", { 3.14,2.718 }, 42, { 0,1,2,3,4,5 });
  • constructor de tupla es explícito, y por lo tanto debe utilizar la sintaxis de inicialización directa:
std::tuple<size_t, size_t, size_t> threeD1 = { 1,2,3 }; //错误
std::tuple<size_t, size_t, size_t> threeD2{ 1,2,3 };    //正确
  • También puede utilizar la función make_pair () para generar unos objetos de tupla:
auto item = std::make_tuple("0-999-78345-X", 3, 20.00);

//item类型为tuple<const char*, int, double>

En tercer lugar, los miembros de acceso tupla

obtener la función ()

  • Podemos utilizar el primer y segundo par de acceder al primer elemento y el segundo elemento del contenedor. Pero el número de miembros del contenedor tupla no se limita, por lo que hay que utilizar la plantilla de la función de la biblioteca estándar para obtener elementos de acceso en la tupla
  • Con el fin de utilizar GET, que tenemos que especificar un argumento de plantilla explícito para indicar el acceso a la primera de varios miembros, los miembros del índice a partir de 0
  • obtener devuelve la referencia miembro especificado
  • Por ejemplo:
auto item = std::make_tuple("0-999-78345-X", 3, 20.00);

auto book = std::get<0>(item);        //返回item第一个成员
auto cnt = std::get<1>(item);         //返回item第二个成员
auto price = std::get<2>(item) / cnt; //返回最后一个成员,并将其除以cnt
std::get<2>(item) *= 0.8;             //打折20%(get返回的是item的引用)

tuple_size plantilla de clase, plantilla de clase tuple_element

  • tuple_size: tiene un valor denominado miembro de datos estáticos públicos, lo que representa la tupla dada en el número de miembros
  • tuple_element: se necesita un índice y un tipo tupla, a continuación, por los miembros del público llamado el tipo de datos que representan los miembros de la miembro especificado de una tupla dado
//item的类型为tuple<const char*, int, double>
auto item = std::make_tuple("0-999-78345-X", 3, 20.00);

//trans为item的数据类型
typedef decltype(item) trans;

//返回item中的数据成员数量
size_t sz = std::tuple_size<trans>::value;

//type为int
std::tuple_element<1, trans>::type cnt = get<1>(item);

Cuatro, operadores relacionales y de igualdad

  • La siguiente es una comparación de contenedores STL regulares:
    • Si los dos contenedores del mismo tamaño y todos los elementos que corresponden a dos dos iguales, entonces los dos recipientes son iguales, de lo contrario, no igual
    • Si los dos no son los mismos recipientes tamaño, pero recipientes más pequeños cada elemento igual al elemento correspondiente en un recipiente más grande, los vasos más pequeños de menos de un recipiente más grande
    • Si dos contenedores no son secuencia de prefijo de otro recipiente, que dependen de un resultado de comparación de un resultado de la comparación no es igual a elemento
  • tupla es similar a los contenedores de reglas de comparación STL, pero:
    • Sólo cuando dos tuplas con el mismo número de miembros se pueden comparar
    • Con el fin de utilizar operadores iguales o desiguales, los miembros de cada par de operador igual o desigual deben ser legales
    • Al igual que en el uso de los operadores relacionales, operadores relacionales para utilizar cada uno de los miembros debe ser legal
  • Por ejemplo:
std::tuple<std::string, std::string> duo("1", "2");

std::tuple<size_t, size_t> twoD(1, 2);
bool b = (duo == twoD);     //错误,string与size_t类型不一致无法比较

std::tuple<size_t, size_t, size_t> threeD(1, 2, 3);
b = (twoD < threeD);        //错误,tuple的成员数量不同

std::tuple<size_t, size_t> origin(0, 0);
b = (origin > twoD);        //正确,b为true

En quinto lugar, el uso de una pluralidad de valor de retorno tupla

  • tupla un uso común de una pluralidad de valor de retorno de una función . Aquí presentamos un paso a paso el caso de demostración
  • Ventas_datos es una clase personalizada, que contiene una serie de precios de los libros, registros de ventas
#include <iostream>
#include <ostream>
#include <sstream>
#include <fstream>
#include <string>
#include <iterator>
#include <vector>
#include <tuple>
#include <algorithm>
#include <numeric>
using namespace std;

struct Sales_data {
    std::string isbn()const { return bookNo; }
    Sales_data(const string& s) :bookNo(s), units_sold(0), revenue(0) {}

    Sales_data &operator+=(const Sales_data &rhs) {
        units_sold += rhs.units_sold;
        revenue += rhs.revenue;
        return *this;
    }

    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};

ostream &operator<<(ostream &os, const Sales_data &item)
{
    os << item.isbn() << " " << item.units_sold << " " << item.revenue << ;
    return os;
}

Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) {
    Sales_data sum = lhs;
    sum += rhs;
    return sum;
}
  • Ahora nos definimos a archivos de variables , utilizadas para las ventas en tiendas todas las librerías:
/*
    vector<Sales_data>代表一家书店的销售情况
    vector<vector>代表所有书店
*/
vector<vector<Sales_data>> files;
  • Escribir una función que devuelve una tupla:
    • Vamos a escribir una función que, para un determinado libro, en la búsqueda de archivos vendidos a través de esta librería libro
    • Para cada uno de ventas de discos, devuelve un tipo tupla, sino el índice de librería y dos iteradores (una posición de índice de los archivos se indica en la librería, libros iteradores vector se denotan en este documento librería <Ventas_datos> primero registros de ventas de artículos y las ventas de posición después del último registro)
    • equal_range algoritmo:
      • Mirando tres parámetros especificados por el elemento dentro del rango especificado iterador
      • El algoritmo por defecto <operador para comparar, porque no hay Ventas_datos <operador, por lo que se pasa un puntero a una función llamada compareIsbn
      • El algoritmo devuelve un par, representa una gama de elementos. Si no lo encuentra, iteradores son iguales, que representa un rango de vacío
//equal_range算法比较函数
bool compareIsbn(const Sales_data& lhs, const Sales_data& rhs)
{
    return lhs.isbn() < rhs.isbn();
}

vector<vector<Sales_data>> files;

//声明一个别名
typedef tuple<vector<Sales_data>::size_type, 
    vector<Sales_data>::const_iterator, 
    vector<Sales_data>::const_iterator> matches;

//返回一个类型为tuple的vector
vector<matches> findBook(const vector<vector<Sales_data>> &files, const string &book)
{
    vector<matches> ret;

    //遍历files
    for (auto it = files.cbegin(); it != files.cend(); ++it)
    {
        //在it所在的书店中寻找名为book的书籍,返回值见上面介绍
        auto found = equal_range(it->cbegin(), it->cend(), book, compareIsbn);

        //如果找到了,添加到ret中
        if (found.first != found.second)
            ret.push_back(std::make_tuple(it - files.cbegin(), found.first, found.second));
    }

    return ret;
}
  • Utilice la tupla devuelve la función:
    • while lee el libro que se llama s en, y luego llamar a la función anterior Findbook para encontrar si hay un libro llamado s
    • Si no es así, Findbook volvió vector está vacío, y luego continuar con el ciclo continúa
    • Si encuentra un uso para una iteración de bucle vector trans, donde cada elemento es una tupla
    • A continuación, obtener obtener una tupla de tres elementos 0,1,2 e imprimir
    • En el que el algoritmo se acumulan (ya que definimos operador de suma Ventas_datos, este algoritmo se puede utilizar). 3 acumular un parámetro a un valor inicial, en el que el parámetro es Ventas_datos cadena de constructor de construir. También, porque se define el Ventas_datos << operador, que puede ser la salida a la ostream
void reportResults(istream &in, ostream &os, const vector<vector<Sales_data>> &files)
{
    std::string s; //要查找的书籍

    while (in >> s)
    {
        auto trans = findBook(files, s);

        if (trans.empty()) {
            std::cout << s << "not found in any stores" << std::endl;
            continue;
        }
        else {
            for (const auto &store : trans) {
                os << "store: " << std::get<0>(store) << std::endl;
                os << "sales: " << std::accumulate(std::get<1>(store), std::get<2>(store), Sales_data(s)) << std::endl;
            }
        }
    }
}

 

Liberadas 1504 artículos originales · ganado elogios 1063 · Vistas de 430.000 +

Supongo que te gusta

Origin blog.csdn.net/qq_41453285/article/details/104661451
Recomendado
Clasificación