Есть ли способ конвертировать базовый тип, хранящийся в QVariant, без специализации приведения? - PullRequest
0 голосов
/ 11 сентября 2018

Давайте рассмотрим этот пример:

QVariant v1(1);
QVariant v2("goofy");
QVariantList list;

list << v1 << v2;

for (const auto& var : list) {
   qdebug() << var;

   // nasty part
   if (var.type == QVariant::Int) {
      int value = var.toInt();

      // do something
   } else if (var.type == QVariant::QString) {
      QString value = var.toString();

      // do something
   }
}

Функция отладки показывает тип внутренней памяти QVariant :

QVariant(int, 1) QVariant(QString, "goofy") 

Есть ли способ избежатьif s и сделать явное приведение для доступа к внутреннему типу?Более конкретно, чтобы получить значение, я хотел бы иметь возможность написать что-то вроде этого:

auto value = var.ToData();

Редактировать : поскольку QVariant может содержать много типов, и вы даже можете добавить пользовательскиетипы на нем, было бы достаточно ограничить проблему только базовыми типами (int, double, bool, string)

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Это возможно, но по цене - а QVariant этого не делает. Есть два связанных подхода:

  1. QVariant может отправлять все операторы для операторов конкретного типа во время выполнения, например, добавление двух QVariant с целыми числами может вызвать int operator+(int,int). Это не сделано, потому что это трудно сделать достаточно общим способом, но если бы вы имели в виду несколько типов - вы, безусловно, могли бы создать свой собственный тип, который это делает. Внутри он может использовать QVariant, но я бы опасался разоблачать его без разбора как QVariant. Однако он может быть преобразован в QVariant, чтобы можно было передать тип, в котором ожидается вариант, но не иметь его как вариант - то есть использовать композицию, а не наследование.

  2. QVariant может реализовывать шаблонную переадресацию типов, которая будет выводить тип на основе того, какие операции над ним выполняются, используя SFINAE и выражения шаблона, и заменять операции в QVariant операциями над вложенным типом, с нет времени выполнения Написание достаточно определенного выражения вывело бы тип, и если оно не было достаточно конкретным, вам нужно было бы предоставить подсказки типов - как в любом функциональном языке с выводом типа.

Когда вы имеете в виду небольшой список типов, любой подход может работать очень хорошо, но с множеством типов QVariant должен поддерживать - включая априори неизвестные пользовательские типы - общий подход, чтобы иметь так много ограничений как быть непригодным. Трудно сказать, не зная, что вы делаете с этими ценностями. Об этом можно сказать больше, если дать менее лаконичное описание, чем //do something.

0 голосов
/ 11 сентября 2018

Нет, это невозможно.Как и любой другой вариант, QVariant в основном действует как объединение.Если вы не знаете тип данных, вы не сможете их получить.Если ваш воображаемый код auto value = var.ToData(); должен работать, тип value должен был бы быть разрешаем во время компиляции - но тогда это вообще не было бы вариантом.

Суть варианта в том, что он позволяет хранить несколько типов в одном значении, и все это делается во время выполнения.Внутренне он хранит тип своего значения, но это значение времени выполнения - поэтому, если вы точно не знаете тип, нет другого способа, кроме как сделать длинный переключатель.

...