251
#include <iostream>
template<class T>
void f(T) { std::cout << 1; }
template<>
void f<>(int*) { std::cout << 2; }
template<class T>
void f(T*) { std::cout << 3; }
int main() {
int *p = nullptr;
f( p );
}
这道题没有那么简单的, 也让我更了解模板
首先在模板解析时不考虑特化版本, 所以这里有两个重载void f(T)
和void f(T*)
, 很简单的我们的p匹配的应该是void f(T*)
这是毋庸置疑的, 因为第二个比第一个更能描述参数特征
那么按理说特化版本的void f<>(int*)
才是最匹配的, 这里为什么不输出2呢?
这里需要搞清楚一件事void f<>(int*)
是哪个模板的特化标准中提到了A declaration of a function template (...) being explicitly specialized shall precede the declaration of the explicit specialization.
说明我们应该先有模板再有特化, void f<>(int*)
是在void f(T*)
之前的. 所以void f<>(int*)
是void f(T)
的特化, 在第一次的选择中void f(T)
已经被淘汰, 故也不选择它的特化版本void f<>(int*)
, 所以输出3
243
#include <iostream>
template <typename T>
struct A {
static_assert(T::value);
};
struct B {
static constexpr bool value = false;
};
int main() {
A<B>* a;
std::cout << 1;
}
第一眼static_assert(false)
秒了, 然后错误
在这个例子中, A<B>
如果被实例化, 那么显然是不能编译通过的, 在程序中并没有出现显式特化或者显式实例化, 那么接下来考虑的就是有没有出现隐式实例化
这里的A<B>
仅仅是指针而不需要对应类型的对象, 所以也没有被隐式实例化, 故可以输出1
你可以看到有没有A<B>* a
这行生成的汇编都一样


评论 (0)