LINUX.ORG.RU

c++ boost::any

 ,


0

1

Народ. Кто нибудь может дать ссылку на какой либо open source project где этот сабж используют. Или может кто сам использует. Не могу представить use case где это может згодится. Заранее всем спасибо.


В ситуациях, где обычно используется void* и reinterpret_cast, boost::any предоставляет типо-безопасную альтернативу.

vector<void *> v{new int(), new std::string()};
for (auto && el : v)
{
    int * n = reinterpret_cast<int *>(el);
    std::cout << *n; // здесь бум!
}

vector<boost::any> v{int(), std::string()};
for (auto && el : v)
{
    if (int * n = boost::any_cast<int>(&el))
        std::cout << *n;  // всё путём
}
rupert ★★★★★
()
Ответ на: комментарий от rupert
enum class Type
{
  Int,
  String
};
struct Arbitrary
{
  Type type;
  void* value;
};

std::vector<Arbitrary> v{ Arbitrary{Int,new int()}, {String, new std::string()} };

for(size_t i = 0, size = v.size(); i < size; i++)
{
  const Arbitrary& el = v[i];
  if(el.type == Int)
  {
    int* n = (int*)el.value;
    std::cout << *n;  // всё путём
  }
}
andreyu ★★★★★
()

Я вот использую — в обходе дерева арифметического выражения (паттерн Visitor). В частности, результатом вычисления узла у меня может быть либо рациональное число (хранимое точно), либо действительное (хранимое в формате с плавающей точкой), либо вообще ничего (если, например, значение какой-либо переменной неизвестно). Например, так: https://github.com/intelfx/data-processing/blob/master/differentiator/visitor...

intelfx ★★★★★
()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от tailgunner

Нет. В QVariant можно добавить поддержку своего типа, в экземпляр boost::variant - нет; ограничить типы, которые могут содержаться в QVariant - нельзя.

Begemoth ★★★★★
()
Последнее исправление: Begemoth (всего исправлений: 1)
Ответ на: комментарий от intelfx

Я посмотрел ваш код: https://github.com/intelfx/data-processing/blob/master/differentiator/visitor-calculate.cpp и на первый взгляд кажется что здесь вполне возможно использовать boost::variant который в качестве бонуса нам дает еще и compile-time checked visitation что может со временем и пригодится. Не могли бы вы обяснить в кратце почему именно boost::any был выбран. Или если я в чем то не прав то поправте. Спасибо всем за ответы.

CunMun
() автор топика
Ответ на: комментарий от CunMun

Потому что Visitor::Calculate — это лишь одна из реализаций; у меня есть и другие visitor-ы, методы visit() которых возвращают значения других типов.

Что касается compile-time checked visitation — это мне ни к чему. Проще, где надо, вручную по очереди откастовать boost::any ко всем нужным типам. Делать для каждого случая отдельный функтор слишком громоздко.

intelfx ★★★★★
()
Ответ на: комментарий от intelfx

Проще, где надо, вручную по очереди откастовать boost::any ко всем нужным типам.

А с boost::variant можно по-очереди пытаться получиться значение каждого типа (boost::get).

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

В QVariant можно добавить поддержку своего типа, в экземпляр boost::variant - нет;

В смысле? Что подразумевается под «нельзя добавить поддержку своего типа»?

DarkEld3r ★★★★★
()
Ответ на: комментарий от intelfx

Из всего этого я понял что boost::any это такой готовый изящный безопасный темплейт который позволяет нам писать легко читаемый аккуратный «шаблонный» код без использования шаблонов и не изобретать велосипеды. Поэтому наверное «нужно» и имеет право на жизнь. Как то так я для себя понял сабж, полистав документацию и посмотрев код.

CunMun
() автор топика
Ответ на: комментарий от DarkEld3r

boost::variant<T1, T2, ..., TN> - тип равный сумме T1, T2, ..., TN (по другому это называется discrimated union). Он может содержать только значения типов T1, T2, ..., TN, никакие другие в него (без преобразований) не поместить. В QVariant-же можно поместить значение любого типа.

Begemoth ★★★★★
()
Ответ на: комментарий от CunMun

boost::any это такой готовый изящный безопасный темплейт который позволяет нам писать легко читаемый аккуратный «шаблонный» код без использования шаблонов

изящный безопасный

легко читаемый аккуратный

Мде. Кажется, это любовь.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Мде. Кажется, это любовь.

Ага с первого взгляда. Может если когда то начну пользовать то смогу более критично оценить эту штуку.

CunMun
() автор топика
Ответ на: комментарий от CunMun

Мде. Кажется, это любовь.

Ага с первого взгляда.

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

tailgunner ★★★★★
()
Ответ на: комментарий от Begemoth

В QVariant-же можно поместить значение любого типа.

Всё, теперь понял. Ну да, типы которые может содержать бустовый вариант фиксируются при обьявлении.

DarkEld3r ★★★★★
()
Ответ на: комментарий от tailgunner

Здесь проверка типа и каст - разные операции, их согласованность не проверяется.

Тут тоже:

if (int * n = boost::any_cast<int>(&el))

andreyu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.