是否可以合法地重载字符串文字和const char *? [英] Is it possible to legally overload a string literal and const char*?

查看:73
本文介绍了是否可以合法地重载字符串文字和const char *?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 11中是否可以重载 const char * 和字符串文字( const char [] )?
的想法是,避免在已经知道该长度的情况下调用 strlen 来查找字符串长度。

Is it possible in C++11 to overload const char*'s and string literals (const char[])? The idea is to avoid having to call strlen to find the string length when this length is known already.

此代码段在G ++ 4.8和Clang ++ 3.2上中断:

This snippet breaks on G++ 4.8 and 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;
}

错误(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;
}

这是有效的C ++ 11吗?删除数组专用化后,字符串文字似乎在 T& 上重载。是什么导致这种歧义得到解决,但第一个代码段中的歧义没有得到解决?

Is this valid C++11? The string literal appears to overload on T&& when the array specialization is removed. 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.

这篇关于是否可以合法地重载字符串文字和const char *?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆