Когда я должен использовать std :: any

Начиная с C ++ 17 std::any вводится. Теперь можно написать код, подобный этому

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

int main () {
const double d = 1.2;
std::any var = d;
const std::string str = "Hello World";
var = str;
}

Двойной присваивается переменной var и чем std::string был назначен на это.

Почему имеет std::any был введен?

Я думаю, что это нарушает least astonishment ruleпотому что мне трудно думать о ситуации, когда это можно использовать для более ясного выражения того, что мне нравится выражать.

Может ли кто-нибудь дать мне хороший пример, когда std::any это выгодно.

https://gcc.godbolt.org/z/-kepOD

7

Решение

Когда использовать

void* как крайне небезопасный шаблон с некоторыми ограниченными случаями использования, std::any добавляет безопасность типов, и поэтому у него есть реальные варианты использования.

Некоторые возможности:

  • В библиотеках — когда тип библиотеки должен содержать или передавать что-либо, не зная
    множество доступных типов.
  • Парсинг файлов — если вы действительно не можете указать, какие поддерживаются
    типы.
  • Передача сообщений.
  • Привязки со скриптовым языком.
  • Реализация переводчика для языка сценариев
  • Пользовательский интерфейс — элементы управления могут содержать что угодно
  • Сущности в редакторе
    (ссылка)
6

Другие решения

Я бы назвал это классическим «используйте, когда вы не можете избежать этого».

Я могу думать только о не критичных к производительности реализациях языков сценариев с динамической типизацией для представления переменных из мира сценариев, но даже с натяжкой (Boost.Spirit / пример / й / compiler_tutorial делает это без, как для парсера и времени выполнения).

Для всего остального от парсеров (например, Boost.Spirit.X3) к API библиотеки (например, ASIO) обычно существует более быстрая / лучшая / более конкретная альтернатива, поскольку очень немногие вещи действительно являются «чем-то», большинство из них более конкретны, чем это.

  • std::variant и / или std::optional для «почти любой стоимости»
  • std::packaged_task / std::function + лямбда-выражения для «обратного вызова с аргументами», что было бы в случае void* в C API.
  • и т.п.

В частности, я бы не стал слепо включать его в качестве замены для void*, как это может выделить памяти в куче, что может быть смертельно опасным для высокопроизводительного кода.

3

Он используется в Wt, чтобы обеспечить не шаблонный интерфейс для табличные данные.

Для встроенных и Wt-типов существуют преобразования в строку, и вы можете зарегистрировать дополнительные преобразования, Wt::any_traits. Это позволяет отображать что-либо как запись в таблице, классы представления не должны ничего знать о типах, которые они отображают.

1

std::any это запас слов тип. Когда вам нужно сохранить что-нибудь, в качестве значения вы можете использовать его.

Существует несколько вариантов использования «первого уровня»:

  1. При взаимодействии с языками сценариев, которые сами имеют такие типы, это естественное соответствие.

  2. Когда у вас есть дерево свойств с очень полиморфным содержимым, и структура дерева отделена от производителя и потребителя дерева.

  3. При замене эквивалента void* кусок данных, передаваемых через промежуточный уровень, которому действительно все равно, что он несет.

Он также может быть использован в качестве строительного блока в других случаях. Например, std::function может выбрать для хранения его значение в std::any:

template<class R, class...Args>
struct func<R(Args...)> {
mutable std::any state;
R(*f)(std::any& state, Args&&...) = nullptr;
template<class T>
void bind(T&& t) {
state = std::forward<T>(t);
f = [](std::any& state, Args&&...args)->R {
return std::any_cast<T&>(state)(std::forward<Args>(args)...);
};
}
R operator()(Args...args)const {
return f(state, std::forward<Args>(args)...);
}
};

это довольно маленькая реализация (большая часть) std::function, В основном я использовал any набрать стереть копировать / переместить / уничтожить.

Вы можете использовать это в другом месте для подобных проблем (где вы стираете какую-либо операцию, а также хотите набрать стирать, копировать / перемещать / уничтожать), или обобщить это.

1
По вопросам рекламы [email protected]