面试题:
写函数判断一个变量是否为指针?
要解决这个问题,要用一个巧妙的方法,先回顾一下相关知识点:
- C++中仍然支持C语言中的可变参数函数
- C++编译器的函数匹配调用优先级
- 重载函数
- 函数模板
- 可变参数函数
Tip:
如果同时存在普通函数和其重载版本、模板函数、可变参数函数,编译器会优先调用普通函数和其重载版本,然后依次时模板函数和可变参数函数!
示例:
#include <cstdlib>
#include <iostream>
using namespace std;
void test(int i, int j)
{
cout<<"int test(int i, int j)"<<endl;
}
template<typename T>
void test(T i, T j)
{
cout<<"T test(T i, T j)"<<endl;
}
void test(...)
{
cout<<"int test(...)"<<endl;
}
int main(int argc, char *argv[])
{
int i = 0;
int j = 0;
test(i, j);
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
运行结果:
知道了上述知识点,就可以解决面试题了!
利用函数模板与可变参数函数的匹配优先级,判断一个变量是否是指针:
#include <cstdlib>
#include <iostream>
using namespace std;
template<typename T>
void IsPtr(T* i)
{
cout<<"true"<<endl;
}
void IsPtr(...)
{
cout<<"false"<<endl;
}
int main(int argc, char *argv[])
{
int *pi = nullptr;
double *pd = nullptr;
int i = 0;
IsPtr(pi);
IsPtr(pd);
IsPtr(i);
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
Tip:
如果是指针类型,编译器就会优先匹配模板函数,如果匹配不上,才匹配可变参数函数!
这种方法虽然解决了问题,但是效率却不高,再做一些改进!
#include <cstdlib>
#include <iostream>
using namespace std;
#define ISPTR(v) (sizeof(IsPtr(v)) == sizeof(int))
template<typename T>
int IsPtr(T* i);
char IsPtr(...);
int main(int argc, char *argv[])
{
int *pi = nullptr;
double *pd = nullptr;
int i = 0;
cout << ISPTR(pi) << endl;
cout << ISPTR(pd) << endl;
cout << ISPTR(i) << endl;
cout << "Press the enter key to continue ...";
cin.get();
return EXIT_SUCCESS;
}
Tip:
上述代码,本质上还是利用函数匹配优先级,但是我们增加了sizeof运算符,该运算符是在编译器就处理的,所以在编译器结果就被计算好了。通过函数返回值的大小差异,来判断编译器调用了哪个函数,从而判断是否是指针!