【发布时间】:2021-12-31 10:48:33
【问题描述】:
我有两个类(结构)模板 A 和 B,除了 第二个参数的默认参数(在它们的主模板中)和 template-specializing第二个论点(在他们的部分特化中)在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 在他的answer 中正确识别的那样,我的困惑是由于期望在实例化B<1> 时,编译器将解析“更专用于N != 0”版本B<N, int>,更喜欢它而不是“更通用" 版本B<N, void>.
【问题讨论】:
-
我不明白你的困惑。您将
A<int>设计为默认为A<int, void>,然后它使用A<int, void>的实例化。您将B<int>设计为默认为B<int, void>,然后它使用B<int, void>的实例化。您还期望发生什么其他事情?
标签: c++ c++11 template-meta-programming sfinae template-specialization