受到另一个问题的启发,试图回答这个问题,我发现 VC ++ 2019 的这种行为对我来说是难以理解的。
编码:
#include <iostream>
using namespace std;
class String
{
public:
String(char* str):p(str){};
const char& operator[](size_t i) const { return p[i]; }
char& operator[](size_t i) { return p[i]; }
operator const char* () const { return p; }
operator char* () { return p; }
private:
char* p;
};
int main() {
char s[] = "123456";
String name = s;
std::cout << name[0] << std::endl;
name[1] = '5';
std::cout << name << std::endl;
}
不要查看内存和其他类似问题的各种可能问题,这只是将代码削减到最低限度。
因此,当将 x64 编译为 string 时cl /EHsc main.cpp,一切都会顺利进行。
但是对于 x86 使用相同的命令,我们得到
main.cpp
main.cpp(20): error C2666: String::operator []: для перегрузок (4) есть подобные преобразования
main.cpp(10): note: может быть "char &String::operator [](size_t)"
main.cpp(9): note: или "const char &String::operator [](size_t) const"
main.cpp(20): note: или "встроенный оператор C++[(const char *, int)"
main.cpp(20): note: или "встроенный оператор C++[(char *, int)"
main.cpp(20): note: при попытке сопоставить список аргументов "(String, int)"
main.cpp(21): error C2666: String::operator []: для перегрузок (4) есть подобные преобразования
main.cpp(10): note: может быть "char &String::operator [](size_t)"
main.cpp(9): note: или "const char &String::operator [](size_t) const"
main.cpp(21): note: или "встроенный оператор C++[(const char *, int)"
main.cpp(21): note: или "встроенный оператор C++[(char *, int)"
main.cpp(21): note: при попытке сопоставить список аргументов "(String, int)"
有人可以解释为什么在为不同平台编译时会有这样的差异吗?...
PS G++:https ://ideone.com/TbDfC2
g++ 的行为类似:
g++ -m32 -c some.c++ -pedantic32 位编译器找到四个选项:
String,转换int为size_t:char& String::operator[](size_t)String,转换int为size_t:const char& String::operator[](size_t) constString为char*,离开类型int:[char *, int]String为const char*,离开类型int:[const char *, int]在所有四种变体中,一种类型被转换,第二种没有。因此,编译器无法选择最佳候选者。
在 64 位情况下,情况有所不同:内置运算符
[]具有签名operator[](char*, long int)由于文字
0是 typeint,上面列表中的选项 3 和 4 变为将类型转换
String为char*,将类型转换int为long int:[char *, long int]将类型转换
String为const char*,将类型转换int为long int:[const char *, long int]由于添加了会降低候选者的提升,因此编译器会丢弃这些候选者。因此,在 64 位的情况下,它编译时不会出错。
为防止编译器考虑内置索引运算符,请显式使文字无符号:
0u和5u. 然后它将编译 64 位和 32 位。PS。内置运算符类型
[]ISO C++ 2020 第 12.7 章
64 位 g++ 用于什么
ptrdiff_t,long int我已经通过实验确定了。