爲了使情況區別使用SFINAE T
型t
參數,我想知道如果語句檢查類型被聲明爲一元類型系統(用於SFINAE)
QVariant::fromValue(t);
和/或
QVariant::value<T>();
編譯。如果一個人編譯,另一個人也會這樣做,除非你破解元類型系統。當且僅當T
已被聲明使用Q_DECLARE_METATYPE(T)
時,它們編譯。
非常簡單的用法示例,其中只需打印一個值的類型就可以打印一個變體包裝的等價物,當且僅當被元類型系統支持時(我不需要這個,但是這顯示了在一個小例子問題):
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_if等。現在,我知道有QTypeInfo
我猜它, ,已經提供了類似於「在Qt元類型系統中聲明的」類型特徵。然而,這個類沒有記錄,因此它不被建議用於長期和高效的代碼,因爲它可能會在Qt版本之間變化。
如果QVariant支持類型T
,是否有一種非常簡單的方法(比使用「checker」+ enable_if更簡單)檢查SFINAE專業化?
請注意,在不同的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-meta系統** ???如果是 - 這是無稽之談 – borisbn
不,我的意思是「聲明」,即存在一個「Q_DECLARE_METATYPE(T)」。對不起,我會糾正它。 – leemes
我能找到的最接近的是'qMetaTypeId()',但是如果'T'未註冊會導致編譯器錯誤 - 不太好。 –
cmannett85