是否有可能合法地重载字符串字面值和const char*

Is it possible to legally overload a string literal and const char*?

本文关键字:字面值 const char 字符串 重载 有可能 是否      更新时间:2023-10-16

是否有可能在c++ 11中重载const char* 's和字符串字面值(const char[])?这样做是为了避免在已知字符串长度的情况下调用strlen来查找字符串长度。

这段代码在g++ 4.8和clang++ 3.2上中断:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
template<typename T, int N>
void length(const T(&data)[N]) {
  printf("%u[]n", N - 1);
}
template<typename T>
void length(const T* data) {
  printf("*%un", (unsigned)strlen(data));
}
int main() {
  length("hello");
  const char* p = "hello";
  length(p);
  return 0;
}

错误(叮当声):

test2.cpp:16:3: error: call to 'length' is ambiguous
  length("hello");
  ^~~~~~
test2.cpp:6:6: note: candidate function [with T = char, N = 6]
void length(const T(&data)[N]) {
     ^
test2.cpp:11:6: note: candidate function [with T = char]
void length(const T* data) {
     ^
1 error generated.

被黑了一下,这似乎行得通:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
template<typename T, int N>
void length(const T(&data)[N]) {
  printf("%u[]n", N - 1);
}
template<typename T>
void length(T&& data) {
  printf("*%un", (unsigned)strlen(data));
}
const char *foo() {
   return "bar";
}
int main() {
  length("hello");
  const char* p = "hello";
  length(p);
  length(foo());
  return 0;
}

在c++ 11中有效吗?当移除数组专门化时,T&&上的字符串字面值似乎会过载。是什么导致这种歧义被解决,而不是第一个代码片段中的歧义?

在第一种情况下,在重载解析期间,您有一个完美匹配,不需要从数组转换到指针转换(这属于"左值转换"类别,以及左值到右值和函数到指针转换)。仅由左值转换产生的差异不足以使重载解析选择赢家。

在第二种情况下,在重载解析期间,两个函数具有完全相同的参数类型。然后,作为最后手段的部分排序发现,第二个模板将接受您传递给它的所有参数,而第一个模板只接受数组。因此,第二种情况下的第一个模板被发现更专门化,并被采用。


至于你的另一个问题——不,专门为字符串文字重载是不可能的。你总是会捕捉到相同大小的数组。