Не могу найти элемент в контейнере с помощью std::any

Этот скрипт

#include <iostream>
#include <unordered_map>
#include <any>
using namespace std;

int main() {
    unordered_map<int, any> test;
    test[5] = "Hey!";
    cout << test[5];
    return 0;
}

Почему это не работает?

candidate function not viable: no known conversion from 'std::__ndk1::unordered_map<int, std::__ndk1::any, std::__ndk1::hash<int>, std::__ndk1::equal_to<int>, std::__ndk1::allocator<std::__ndk1::pair<const int, std::__ndk1::any> > >::mapped_type' (aka 'std::__ndk1::any') to 'const void *' for 1st argument; take the address of the argument with &
    basic_ostream& operator<<(const void* __p);

Извините, если это звучит немного глупо

Вам нужно std::any_cast его к определенному типу

UnholySheep 13.05.2022 12:01

Вы ничего не можете сделать с std::any напрямую, вам нужно использовать std::any_cast для извлечения содержащегося значения

Alan Birtles 13.05.2022 12:01

@AlanBirtles не совсем верно. Вы можете скопировать или переместить any или заменить содержащееся в нем значение.

Caleth 13.05.2022 12:05

Вы должны привыкнуть к чтению документации на регулярной основе. станд:: любой

digito_evo 13.05.2022 12:05
std::any это круто, но нужно довольно редко. Смешивать его с std::unordered_map странно. Вот почему я бы порекомендовал вам объяснить, почему, по вашему мнению, ваш код нуждается в std::unordered_map<int, std::any>, я уверен, что есть лучшее решение для вашей задачи, которую должен решить ваш код.
Marek R 13.05.2022 12:14

Неоднородный массив пользовательских входных данных, использующий unordered_map<int, чтобы пользователь мог пропускать значения (я уверен, что есть лучший способ сделать это, которого я не знаю)

Bfyuvf 13.05.2022 12:18
std::variant может быть более подходящим, если разрешенные типы ограничены
Jarod42 13.05.2022 12:22

Итак, any_cast работает, но что, если я даже не знаю, какой тип охватывает any? Создание catch() для каждого типа неэффективно

Bfyuvf 14.05.2022 09:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Чтобы устранить ошибку, вы можете использовать std::any_cast, который дает безопасный доступ к содержащемуся объекту, как показано ниже:

std::cout <<  std::any_cast<const char*>(test[5]);

Или

test[5] = std::string("Hey!");    
std::cout <<  std::any_cast<std::string>(test[5]);

Это связано с тем, что не существует определенной перегрузки для оператора << для std::ostream и std::any.

<< определен для строковых литералов, std::strings, чисел и некоторых других конкретных объектов. std::any не является ни тем, ни другим.

Тот факт, что он действительно содержит строку, не превращает его в std::string или что-то еще. Просто потому, что вы открываете дверь своей машины, заходите внутрь и садитесь, или сажаете в машину собаку, или кучу продуктов, не превращает вашу машину в человека, собаку или кучу овощей. Это все еще машина, просто в ней что-то есть.

Таким образом, для этого не определен оператор <<. Вот что говорит вам ваш компилятор C++: ему нужен оператор <<, определенный для std::ostream и std::any, а его нет.

Ответ принят как подходящий

Просто добавьте any_cast к test[5]. Основная причина этого приведения заключается в том, чтобы сообщить компилятору, какая перегруженная функция << должна быть вызвана для test[5], << не имеет никакой функции, определенной для std::any. Следовательно, мы сказали компилятору вызвать const char * или std::string функцию перегрузки <<.

Всегда следите за тем, чтобы sizeof распределения test[n] соответствовало типу sizeof. Например:

sizeof(std::string) = 32 bytes

sizeof(const char *) = 8 bytes

Вот почему нам сначала нужно выделить test[5] с помощью std::string("Hey!");, а не просто "Hey!".

Но sizeof(int *) равно sizeof(char *), если вы это сделали, это может вызвать 3 проблемы:

  1. сегментация
  2. неопределенное поведение
  3. Исключение: std::bad_any_cast

Исправить

std::cout << std::any_cast<const char *>(test[5]);

или std::string

test[5] = std::string("Hey!");
std::cout << std::any_cast<std::string>(test[5]);

Другие вопросы по теме