我有兩個類(結構)模板Aand B,它們是相同的,除了第二個引數的默認引數(在它們的主模板中)和模板特化的第二個引數(在它們的部分特化中)在A(兩者void)中是相同的,而在B(void和int分別)。
#include <bits/stdc .h>
/* primary class template A */
template <int N, class = void>
struct A : std::false_type {};
/* partial specialization of A */
template <int N>
struct A<N, std::enable_if_t<(N != 0), void>> : std::true_type {};
/* primary class template B */
template <int N, class = void>
struct B : std::false_type {};
/* partial specialization of B */
template <int N>
struct B<N, std::enable_if_t<(N != 0), int>> : std::true_type {};
int main() {
std::cout << A<0>::value << std::endl; // 0 (i.e. A<0> extends std::false_type)
std::cout << A<1>::value << std::endl; // 1 (i.e. A<1> extends std::true_type)
std::cout << B<0>::value << std::endl; // 0 (i.e. B<0> extends std::false_type)
std::cout << B<1>::value << std::endl; // 0 (i.e. B<1> extends std::false_type)
return 0;
}
從輸出B<1>可以理解,決議為主模板,而A<1>決議為部分特化,我猜這是由于上述差異而發生的。這是相當違反直覺的,因為我預計會發生完全相反的情況。但為什么會發生呢?編譯器如何決定要決議哪個版本,特別是在這種情況下?
編輯:
正如@Enlinco 在他的回答中正確識別的那樣,我的困惑是由于期望在實體化時B<1>編譯器會決議“更專業化N != 0”版本B<N, int>,而不是“更通用”版本B<N, void>。
uj5u.com熱心網友回復:
如果我理解混亂,當你看到
/* primary class template B */
template <int N, class = void>
struct B : std::false_type {};
/* partial specialization of B */
template <int N>
struct B<N, std::enable_if_t<(N != 0), int>> : std::true_type {};
你認為當編譯器看到B<1>in 時main,
- 它看到通用模板沒問題,
- 然后它會看到專業化和
- 看到的
(N != 0)是true, - 做出決議
std::enable_if_t<(N != 0), int>,以int - 因此導致
B<1, int>,這是好的并且是首選,因為它是一個專業。
- 看到的
故事略有不同。
線
template <int N, class = void>
只是意味著,正如評論中所建議的那樣,當您撰寫編譯器時,會看到.B<an-int>B<an-int, void>
如果您從這個角度來看它,您應該明白為什么不匹配會導致您觀察到的行為:B<1>is just B<1, void>,并且沒有專門針對此。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/364331.html
上一篇:宣告內部類模板欄位時出錯
