怎样区分 const char* 和字符串文字量
在一个面试中,猛然间一闪念,问到了 candidate 这个问题。无解……
stl 中使用到了很多 traits 技术,只要懂得 traits ,这个问题就太简单了!以下是代码示例:
软件工程中很多地方,如果采用直接的办法不能解决问题,增加一个间接层,问题即迎刃而解,type_traits 就是这样一种技术,这个代码示例是自包含的,除了 printf ,没有任何其它外部依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <stdio.h> struct true_{}; struct false_{}; template<class T> struct isarray; template<class T, int N> struct isarray<T[N]> { typedef true_ type; }; template<class T> struct isarray<T* > { typedef false_ type; }; void f(const char* s, false_) { printf("const char*/n"); } template<int N> void f(char const (&s)[N], true_) { printf("const char[N=%d]/n", N); } template<class T> void f(const T& x) { f(x, typename isarray<T>::type()); } int main() { const char* pc = "abc"; const char s[] = "1234"; f("123"); f(s); f(pc); return 0; } |
为什么下面这样的代码不能work?
1 2 3 4 5 6 7 |
void f(const char* s) { printf("const char*/n"); } template<int N> void f(char const (&s)[N]) { printf("const char[N=%d]/n", N); } |
答案:C++的重载匹配规则:如果在非模板的候选中能找到一个”精确”匹配,就不会去找模板。”精确”的精确定义包含3大类,5种具体情况,按顺序如下:
Identity Conversion —- 不需要任何转化,最精确,级别 1
Lvalue to Rvalue Conversion — 左值到右值转化, 级别 2
Array to Pointer Conversion — 数组到指针转化, 级别 3
Function to Pointer — 函数名到函数指针, 级别 4,这就是为什么很多时候我们不需要使用 &func_name 而直接使用 func_name
Quolification Conversion — cv qualify 少的可以转化到 cv qualify 多的,级别 5
这也就是为什么下面的代码可以 work:
1 2 3 4 5 6 7 |
template<class T> void f(T x) { printf("f(T)/n"); } void f(int x) { printf("f(int)/n"); } ..... f(1); // call f(int) f(1L); // call f(T) f('c'); // call f(T) |
char -> int 不是 exact match, 是 integeral promotion.
long -> int 不是 exact match, 是 integeral conversion.
最让人郁闷的还是,面对const char* , std::string居然竞争不过bool
[reply]zy498420[/reply]
std::string(const char*) is user defined conversion;
const char* to bool is standard conversion;
standard conversion has higher rank than user defined conversion.
beside this, make bool as parameter is a bad programming style.
[reply]whinah[/reply]
"…make bool as parameter is a bad programming style"
That's it! But it was used in library design, not app programming.