Чтобы сделать тематическое различие для параметра t
типа T
с помощью SFINAE, я хочу знать, если заявлениеПроверьте тип объявлен как мета-системы типа (для SFINAE)
QVariant::fromValue(t);
и/или
QVariant::value<T>();
компилируется. Если один компилируется, другой делает тоже, если вы не взломаете систему мета-типа. Они компилируются тогда и только тогда, когда T
был объявлен с использованием Q_DECLARE_METATYPE(T)
.
Очень простой пример использования, когда вы хотите напечатать тип значения, просто qDebugging эквивалентный вариант, если и только если поддерживается системой мета-типа (мне это не нужно, но это показывает проблема в минимальном примере):
template<class T> // enable if T NOT registered in the Qt meta type system
void print(const T &t) {
qDebug() << t;
}
template<class T> // enable if T registered in the Qt meta type system
void print(const T &t) {
qDebug() << QVariant::fromValue<T>();
}
Я знаю несколько (пока подобные) возможности сделать это, но все из них ввести некоторые вспомогательные структуры, сложные enable_ и т.д. Теперь я знаю, что есть QTypeInfo
, который, я думаю, , уже предоставляет нечто вроде функции «объявляется в типе системы типа Qt». Однако этот класс не документирован, и поэтому не рекомендуется использовать его в долгосрочном и продуктивном коде, поскольку он может меняться между версиями Qt.
Есть ли очень простой способ (проще, чем с «checker» + enable_if) проверять специализацию SFINAE, если QVariant поддерживает тип T
?
Обратите внимание, что решение по-прежнему должно быть портативным между различными версиями Qt (Qt4 и Qt5 могут использовать другое определение QTypeInfo
). Тем не менее, я использую C++ 11, поэтому у меня есть доступ к std::enable_if
, например.
«Непортативный» способ заключается в использовании внутреннего определения QMetaTypeId2<T>::Defined
в enable_if
(это значение перечисления, определяемое как 0 или 1). Таким образом, рабочий раствор будет:
template<class T>
typename std::enable_if<!QMetaTypeId2<T>::Defined>::type
print(const T &t) {
qDebug() << t;
}
template<class T>
typename std::enable_if<QMetaTypeId2<T>::Defined>::type
print(const T &t) {
qDebug() << QVariant::fromValue<T>();
}
Однако, поскольку QMetaTypeId2
не документирован и только внутренний материала, он не должен появляться в коде клиента.
Исправьте меня, если я ошибаюсь: вы хотите знать в ** время компиляции ** сделал ли какой-либо тип зарегистрированным в Qt-мета-системе в ** время выполнения ** ??? Если да - это абсурд – borisbn
Нет. Я имею в виду «объявленный», то есть присутствует «Q_DECLARE_METATYPE (T)». Извините, я исправлю это. – leemes
Ближайшим, что я могу найти, является 'qMetaTypeId()', но он вызывает ошибку компилятора, если 'T' незарегистрирован - не так хорошо. –
cmannett85