Когда я должен использовать std :: any - PullRequest
0 голосов
/ 09 октября 2018

Поскольку 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

Ответы [ 4 ]

0 голосов
/ 09 октября 2018

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, чтобы напечатать erase copy / move / destroy.

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

0 голосов
/ 09 октября 2018

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

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

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

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

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

0 голосов
/ 09 октября 2018

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

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

0 голосов
/ 09 октября 2018

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

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

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