Преобразование std::any в неизвестный тип

Если у меня есть std::any из std::string или int, как я могу привести это к содержащемуся типу?

std::any имеет type, однако я не могу использовать этот тип для приведения.

Пример:

#include <any>
#include <iostream>
#include <string>

int main(void) {
    std::any test = "things";
    std::any test2 = 123;

    // These don't work
    std::string the_value = (std::string) test;
    int the_value2 = (int) test2;

    std::cout << the_value << std::endl;
    std::cout << the_value2 << std::endl;
}

person innectic    schedule 17.10.2017    source источник
comment
en.cppreference.com/w/cpp/utility/any/any_cast   -  person Mankarse    schedule 17.10.2017
comment
Обратите внимание, что test не содержит std::string. "things" не std::string.   -  person Barry    schedule 17.10.2017


Ответы (2)


Если у вас нет списка типов, среди которых any содержит один, вы не можете преобразовать any в его тип и работать с ним как с реальным типом.

Вы можете сохранить тип в any и операцию в этом типе как указатель на функцию в этом any. Но это нужно делать в момент сохранения или когда у вас есть список (возможно, с 1 элементом) возможных типов, хранящихся в any.

C++ не хранит достаточно информации внутри any, чтобы разрешить компиляцию произвольного кода для этого типа, когда он сохраняет значение в any. C++ не допускает полной "реификации" во время выполнения.

тип стирания типа стирания, `любые` вопросы? Вопросы и ответы пользователя stackoverflow с дурной репутацией дают пример того, как запомнить некоторые операцию над содержимым any, забывая при этом сохраненный тип.

Если у вас есть такой список возможных типов, рассмотрите возможность использования variant. any существует в узком окне, где вы не знаете типы, хранящиеся во время разработки контейнера, но делаете это как при вставке, так и при удалении.

В этом узком окне вы можете выполнять тесты времени выполнения на основе сохраненного идентификатора типа и приводить его к известному типу с помощью any_cast.

person Yakk - Adam Nevraumont    schedule 17.10.2017

Вы используете any_cast, чтобы добиться цели. Например

auto a = std::any(12); 
std::cout << std::any_cast<int>(a) << '\n'; 

Дополнительную информацию можно найти на странице cppreference.

Если вы хотите динамически преобразовать значение в std::any, вы можете попробовать

if (a.type() == typeid(int)) {
    cout << std::any_cast<int>(a) << endl;
} else if (a.type() == typeid(float)) {
    cout <<  std::any_cast<float>(a) << endl;
}
person CS Pei    schedule 17.10.2017
comment
Я понимаю, что я могу сделать это так, но я ищу кастинг, не зная типа - person innectic; 17.10.2017
comment
Вы имеете в виду использование идентификатора типа для динамического приведения? - person CS Pei; 17.10.2017
comment
@innectic Типы (std::string и int) тоже известны в вашем примере. Можете ли вы привести пример с неизвестными типами? - person Tavian Barnes; 17.10.2017