为什么char []和char*作为typedef不同,但有时......不是?

Who*_*aig 13 c++ decltype

因为我是按照下观察出现了这个问题,char[]char*分歧.

#include <iostream>

typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
    std::cout << std::is_same<decltype(x), decltype(y)>::value << '\n';
    std::cout << std::is_same<ar, pr>::value << '\n';
}

int main()
{
    char data[] = "data";
    char *ptr = data;
    f2(data,ptr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出(在Apple LLVM版本4.2(clang-425.0.28)上)

1
0
Run Code Online (Sandbox Code Playgroud)

为什么这些报告为不同的类型,但没有不同decltype()的?我怀疑它们实际上是由于它们的声明而不同类型typedef,但那么为什么变量报告为相同类型?

Kei*_*son 20

在C++中,与C一样,声明为数组类型的参数在编译时被调整为指针类型,特别是指向数组元素类型的指针.

无论是直接指定数组类型还是通过typedef指定,都会发生这种情况(请记住,typedef不会创建新类型,只是现有类型的别名).

所以这:

typedef char ar[];
typedef char* pr;
void f2(ar x, pr y)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

真正意思:

void f2(char* x, char* y)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

C和C++共享的另一个规则是,在大多数但不是所有上下文中,数组类型的表达式被隐式转换为指向数组对象的第一个元素的指针.这意味着如果您定义一个数组对象:

char arr[10];
Run Code Online (Sandbox Code Playgroud)

您可以使用该对象的名称作为带参数的函数的char*参数(这会丢失边界信息).

在C中,发生此隐式转换的情况是:

  1. 当数组表达式是操作数时sizeof(sizeof arr产生数组的大小,而不是指针的大小);
  2. 当数组表达式是一元的操作数时&(&arr是指向数组的指针,而不是指向指针的指针); 和
  3. 当数组表达式是用于初始化数组类型对象的字符串文字(char s[] = "hello";初始化s为数组,而不是指针).

这些情况(或C++中出现的其他情况)都不会出现在你的程序中,所以你的电话:

f2(data,ptr);
Run Code Online (Sandbox Code Playgroud)

将两个类型的指针值传递char*f2.

里面f2的参数对象xy类型都是char*,所以std::is_same<decltype(x), decltype(y)>::value是真实的.

但类型arpr不同.ar是一个不完整的数组类型char[],pr是指针类型char*.

这解释了你的程序的输出.奇怪之处是因为x您使用数组类型定义的参数ar实际上是类型char*,与类型相同pr.