我對 SFINAE 還是很陌生,想知道如果多個std::enable_if_t<true, std::is_...<T>>最終應用到T.
就像在這個例子中一樣:
template<typename T, typename = void>
class Thing {
// Thing A
};
template<typename T>
class Thing<T, std::enable_if_t<true, std::is_scalar<T>> {
// Thing B
};
template<typename T>
class Thing<T, std::enable_if_t<true, std::is_float<T>> {
// Thing C
};
template<typename T>
class Thing<T, std::enable_if_t<true, std::is_signed<T>> {
// Thing D
};
template<>
class Thing<float> {
// Thing E
};
int main(){
Thing<float> x; // what order would the compiler try out?
}
我認為它會嘗試選擇最“具體”的模板專業化,所以E首先,也是A最后,但這就是我所確定的。我不知道它如何消除 , 或 的歧義,或者B如果我需要控制消歧程序,如何組合多個條件。CDT
uj5u.com熱心網友回復:
還要回答這個問題:不,這種優先級不存在。enable_if 的操作雖然很聰明,但它要么失敗要么成功替換。更重要的是,替換發生在任何潛在的實體相互比較之前。此比較的規則很復雜,但在您的示例中,它確實歸結為選擇最專業的選項,使用以下排名:
- 事物 A 是主要的(最不專業的)模板;
- 事物 B、C 和 D 同樣專業化,但比 A 更專業化;
- E是最專業的。
因此將選擇 E。B、C 和 D 必須考慮,因為它們的條件都被評估為true,并且它們同樣專業化,因為它們每個都有一個型別引數T。由于一個有效的程式必須對名稱的每次使用都有一個明確的匹配,如果從示例中洗掉 Thing E,您將收到編譯器錯誤。
現在,您可以通過使用具有更合適(組合)條件的 enable_if 來消除 B、C 和 D 的歧義,并且歧義問題不會通過使用概念神奇地消失。但是,您可以直接將概念與模板引數一起使用,如下所示:
#include <concepts>
template<typename T>
class Thing {}; // Thing A
template<std::integral T>
class Thing<T> {}; // Thing B
template<std::signed_integral T>
class Thing<T> {}; // Thing C
template<std::floating_point T>
class Thing<T> {}; // Thing D
template<>
class Thing<float> {}; // Thing E
int main() {
Thing<float> E;
Thing<double> D;
Thing<int> C;
Thing<bool> B;
Thing<void> A;
}
這只是一個簡短的示例,但我認為概念是對通用 C 的重大改進,因此它們應該與模板同時被教授和學習。它們現在得到了廣泛的支持,所以如果你碰巧有一個舊的編譯器,你可以隨時在Compiler Explorer上試用它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/522045.html
