Utilize std::any do C++ Moderno nos seus projetos

Dê adeus de uma vez por todas ao void*.

std::any é um recurso da biblioteca padrão C++ que foi introduzido no C++17.

Este componente pertence ao conjunto de classes de contêineres com segurança de tipo, fornecendo um meio seguro para ar…


This content originally appeared on DEV Community and was authored by Marcos Oliveira

Dê adeus de uma vez por todas ao void*.

std::any é um recurso da biblioteca padrão C++ que foi introduzido no C++17.

Este componente pertence ao conjunto de classes de contêineres com segurança de tipo, fornecendo um meio seguro para armazenar e manipular valores de qualquer tipo.

Ele é especialmente útil quando você precisa lidar com situações em que o tipo da variável pode(pleonasmo): variar! 😃

Aí você diz:

— Ah, cara! De boa. Para esses casos eu uso o void *.

Sim, realmente você tem razão, mas você já viu como a nova geração está em relação a segurança de memória ???

Lembrando que o termo segurança é usado em Português, pois não existe uma palavra que se adeque a tradução para Safe, ou seja: Safe Seguro)! 😛

Sem dizer que void * é realmente perigoso!

Se você fizer isso, funciona:

void * some_data; // Péssima ideia

std::string str = "Oi";
int x = 3;
decltype(x) y = 6;

some_data = &str;
std::cout << *(std::string*)some_data << '\n';

some_data = &x;
std::cout << *(int*)some_data << '\n';

some_data = &y;
std::cout << "Tipo de y: " << typeid(y).name() << '\n'; // include typeinfo

Mas, a chance de isso dar mer%$a é grande! Ao final do uso dessas variáveis, some_data vai continuar existindo, ou seja, tempo de vida indefinido!

E é para subsitituir o void* que o std::any foi criado no C++ Moderno que, com certeza, é totalmente Safe!

Em outras palavras, ele é um wrapper que encapsula sua variável para um shared_ptr(ponteiros inteligentes) da vida! Sim, e existe até um std::make_any!!!

Como utilizar o std::any

Primeiramente você precisa incluir o cabeçalho dele:

Logicamente, só funciona a partir do C++17 como foi dito no início!

#include <any>

E agora o mesmo código que foi apresentado acima, mas usando std::any:

#include <iostream>
#include <any>

int main(){
  std::any some_data;

  std::string str = "Oi";
  int x = 3;
  auto y = std::make_any<decltype(x)>(6);

  some_data = str;
  std::cout << std::any_cast<std::string>(some_data) << '\n';

  some_data = x;
  std::cout << std::any_cast<int>(some_data) << '\n';

  some_data = y;
  std::cout << "Tipo de y: " << some_data.type().name() << '\n';
}

No código acima vimos que:

  • std::any some_data; - Declara a variável;
  • std::any_cast<T>(some_data) - Converte para o tipo desejado;
  • std::make_any<T> - Outra forma de criar objetos;
  • some_data.type().name() - Obtém o tipo de dado sem precisar de typeinfo.

E você pode usar pra absolutamente tudo: std::vector, Lambda e tudo que existir de tipo de dado!

E o cara pergunta outra coisa:

— Tá! E se eu quiser acabar o tempo de vida do std::any manualmente?

Basta usar a estrutura de união reset ou até mesmo com o operador de incialização:

some_data.reset();
// Ou
some_data = {};

— E pra verificar se std::any está vazio?
Use has_value():

std::cout << (some_data.has_value() ? "Cheio!" : "Vazio.") << '\n';

O type() sem união com name() pode ser usado para comparar tipos:

std::cout << (some_data.type() == typeid(void)) << '\n'; // 0 pra false
std::cout << (some_data.type() == typeid(int)) << '\n'; // 1 pra true

Para usar os nomes booleanos use: std::cout << std::boolalpha << (some_data.type() == typeid(int)) << '\n';.

Para lançar exceções você deve usar o std::bad_any_cast:

try {

  std::any any_str("Oiii");
  auto my_any{ std::make_any<std::string>(any_str.type().name()) };
  std::cout << std::any_cast<std::string>(my_any) << '\n';

}catch (const std::bad_any_cast& e) {
  std::cerr << "Error: " << e.what() << std::endl;
}

Para verificar se realmente tudo está entre os conformes, nunca se esqueça de usar as flags para seu compilador: -Wall -Wextra -pedantic -g -fsanitize=address.

Além de totalmente SAFE, o std::any é muito prático e uma mão na roda!

Tinha um projeto da empresa que eu estava desenvolvendo, que passava um argumento de função e podia ser qualquer tipo, mas o retorno da função era std::string concatenada ao nome do objeto recebido.

E alguém havia criado um baita de um switch case para converter para std::string(bizarro!), eu subsititui para recebimento de parâmetro para std::any e converti com std::any_cast<std::string> e resolvi de forma: Moderna, Safe e Like a Boss! Exatamente isso que std::any é!!! 😃

Para mais informações acesse: https://en.cppreference.com/w/cpp/utility/any


This content originally appeared on DEV Community and was authored by Marcos Oliveira


Print Share Comment Cite Upload Translate Updates
APA

Marcos Oliveira | Sciencx (2024-06-20T23:10:20+00:00) Utilize std::any do C++ Moderno nos seus projetos. Retrieved from https://www.scien.cx/2024/06/20/utilize-stdany-do-c-moderno-nos-seus-projetos/

MLA
" » Utilize std::any do C++ Moderno nos seus projetos." Marcos Oliveira | Sciencx - Thursday June 20, 2024, https://www.scien.cx/2024/06/20/utilize-stdany-do-c-moderno-nos-seus-projetos/
HARVARD
Marcos Oliveira | Sciencx Thursday June 20, 2024 » Utilize std::any do C++ Moderno nos seus projetos., viewed ,<https://www.scien.cx/2024/06/20/utilize-stdany-do-c-moderno-nos-seus-projetos/>
VANCOUVER
Marcos Oliveira | Sciencx - » Utilize std::any do C++ Moderno nos seus projetos. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/20/utilize-stdany-do-c-moderno-nos-seus-projetos/
CHICAGO
" » Utilize std::any do C++ Moderno nos seus projetos." Marcos Oliveira | Sciencx - Accessed . https://www.scien.cx/2024/06/20/utilize-stdany-do-c-moderno-nos-seus-projetos/
IEEE
" » Utilize std::any do C++ Moderno nos seus projetos." Marcos Oliveira | Sciencx [Online]. Available: https://www.scien.cx/2024/06/20/utilize-stdany-do-c-moderno-nos-seus-projetos/. [Accessed: ]
rf:citation
» Utilize std::any do C++ Moderno nos seus projetos | Marcos Oliveira | Sciencx | https://www.scien.cx/2024/06/20/utilize-stdany-do-c-moderno-nos-seus-projetos/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.