是否可以在 C++11 中重载 const char*
和字符串文字 (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("*%u\n", (unsigned)strlen(data));
}
int main() {
length("hello");
const char* p = "hello";
length(p);
return 0;
}
错误(Clang):
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("*%u\n", (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&&
上重载。是什么导致这种歧义得到解决,但不是第一个代码片段中的那个?
最佳答案
在第一种情况下,在重载解析期间,您有一个完美匹配,不需要将数组转换为指针转换(属于“左值转换”类别,以及左值到右值和函数到指针的转换)。仅由左值转换产生的差异不足以使重载决议选出获胜者。
在第二种情况下,在重载决议期间,两个函数具有完全相同的参数类型。然后,作为最后手段的部分排序发现第二个模板将接受您曾经传递给它的所有参数,而第一个模板只接受数组。因此,发现第二种情况下的第一个模板更专业并被采用。
至于您的其他问题-不,不可能专门为字符串文字重载。你总是会和它们一起捕获相同大小的数组。
关于c++ - 是否可以合法地重载字符串文字和 const char*?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16708307/