【问题标题】:Is it possible to legally overload a string literal and const char*?是否可以合法地重载字符串文字和 const char*?
【发布时间】:2013-05-23 07:44:13
【问题描述】:

在 C++11 中是否可以重载 const char* 和字符串文字 (const char[])? 这个想法是避免在已知字符串长度时调用strlen 来查找字符串长度。

这个 sn-p 在 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&amp;&amp; 上过载。是什么导致这种歧义得到解决,但不是第一个代码 sn-p 中的那个?

【问题讨论】:

  • 奇怪,我得到different behaviour,这取决于char 是否是模板参数...
  • This answer 有一些关于正在发生的事情的相关信息......
  • @KerrekSB:坦率地说,这很不舒服 :(
  • 在第一个 sn-p 中,您可以将第二个模板的参数更改为 const T* const&amp;,然后它应该可以工作了。
  • 您必须重载 const T(&amp;data)[N]const T* const &amp; data 而不是 const T* data。当然,这两个函数都必须是模板函数,否则演绎优先级将不相等,编译器将选择非模板函数而不是模板函数。例如,这些不起作用:const char(&amp;data)[N]const char * const &amp; data

标签: c++ templates c++11 overloading


【解决方案1】:

在第一种情况下,在重载解析期间,您有一个完美的匹配,不需要将数组转换为指针转换(属于“左值转换”类别,以及左值到右值和函数到指针的转换)。仅由左值转换产生的差异不足以使重载决议选出获胜者。

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


至于您的其他问题-不,不可能专门为字符串文字重载。你总是会和它们一起捕获相同大小的数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多