受到另一个问题的启发,试图回答这个问题,我发现 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++ -pedantic
32 位编译器找到四个选项:
String
,转换int
为size_t
:char& String::operator[](size_t)
String
,转换int
为size_t
:const char& String::operator[](size_t) const
String
为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
我已经通过实验确定了。