简体   繁体   English

是否可以合法地重载字符串文字和const char *?

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

Is it possible in C++11 to overload const char* 's and string literals ( const char[] )? 在C ++ 11中是否可以重载const char*和字符串文字( const char[] )? The idea is to avoid having to call strlen to find the string length when this length is known already. 这样做的目的是避免在已知字符串长度时调用strlen来查找字符串长度。

This snippet breaks on G++ 4.8 and Clang++ 3.2: 此代码段在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;
}

Error (Clang): 错误(C声):

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.

Hacked a bit, and this appears to work: 有点黑,这似乎起作用:

#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;
}

Is this valid C++11? 这是有效的C ++ 11吗? The string literal appears to overload on T&& when the array specialization is removed. 删除数组专用化后,字符串文字似乎在T&&上过载。 What causes this ambigousness to be resolved, but not the one in the first code snippet? 是什么导致这种歧义得到解决,但第一个代码片段中的歧义没有得到解决?

In the first case, during overload resolution you have a perfect match requiring no conversion against an array to pointer conversion (which is in the category "lvalue transformation", along with lvalue to rvalue and function to pointer conversion). 在第一种情况下,在重载解析期间,您将拥有一个完美的匹配条件,无需对数组进行指针到指针的转换(属于“左值转换”类别,左值到右值以及函数到指针的转换)。 A difference that is only made by an lvalue transformation is not sufficient for overload resolution to pick a winner. 仅通过左值变换产生的差异不足以使重载分辨率选择获胜者。

In the second case, during overload resolution, both functions have the exact same parameter type. 在第二种情况下,在重载解析期间,两个函数具有完全相同的参数类型。 Then partial ordering as the last resort finds that the second template would accept all arguments you ever pass to it, wheras the first template only accepts arrays. 然后作为最后的选择的部分排序发现第二个模板将接受您传递给它的所有参数,而第一个模板仅接受数组。 Therefor the first template in the second case is found more specialized and taken. 因此,发现第二种情况下的第一个模板更加专业化并采用。


As for your other question - no, overloading specifically for string literals is not possible. 至于您的其他问题-不,不可能专门针对字符串文字进行重载。 You are always going to catch arrays of the same size along with them. 您总是会和它们一起捕获相同大小的数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM