typedef 一个包含 const 元素的数组,使用 const ArrayType 或 c++ 中的 ConstAr

typedef an array with const elements using const ArrayType or ConstArrayType in c++

本文关键字:const 使用 ArrayType ConstAr 中的 c++ 数组 元素 一个 typedef 包含      更新时间:2023-10-16

我将定义一些具有固定大小和常量元素的数组。
我尝试使用typedef,但似乎有些混乱:

typedef int A[4];
typedef const int CA[4];
const A a = { 1, 2, 3, 4 };
CA ca = { 1, 2, 3, 4 };
a[0] = 0;
ca[0] = 0;
a = ca;
ca = a;

所有赋值都会导致上面的代码出现语法错误,我认为a[0] = 0;测试之前应该是合法的。

考虑到指针,
结果更容易理解p[0] = 0;cp = p;是正确的。

typedef int *P;
typedef const int *CP;
const P p = new int[4]{ 1, 2, 3, 4 };
CP cp = new int[4]{ 1, 2, 3, 4 };
p[0] = 0;
cp[0] = 0;
p = cp;
cp = p;

为什么 cv 限定符在指针和数组上的行为不同?
是因为数组已经是一个常量指针,然后编译器进行了一些隐式转换吗?

附言我在Visual Studio 2013上编译了代码。

这两个

声明

const A a = { 1, 2, 3, 4 };
CA ca = { 1, 2, 3, 4 };

是完全等价的,并声明常量数组。如果要运行此简单程序(例如使用 MS VC++(

#include<iostream>
typedef const int CA[4];
typedef int A[4];
int main()
{
    std::cout << typeid( CA ).name() << std::endl;
    std::cout << typeid( const A ).name() << std::endl;
    return 0;
}

对于两个输出语句,您将获得相同的结果

int const [4]
int const [4]

事实上你可以写

#include<iostream>
typedef int A[4];
typedef const A CA;
int main()
{
    std::cout << typeid( CA ).name() << std::endl;
    std::cout << typeid( const A ).name() << std::endl;
    return 0;
}

结果相同。

至于指针声明符,那么语义有细微的区别。您可以将 cv 限定符与指针声明符一起使用

ptr-operator:
    * attribute-specifier-seqopt cv-qualifier-seqopt

那就是你可以写例如

typedef const int * const P;

(指向常量数据的常量指针(。

因此,如果你会写

typedef int *P;

然后写

typedef const P CP;

CP将是一个恒定的指针。它指向的对象不是常量。只有指针本身是恒定的,不能更改。那就是宣言

typedef const P CP;

相当于

typedef int * const CP;

它与

typedef const int *CP;

其中,在最后一个声明中,指针本身不是常量。它是指针指向的对象,具有此类型将是常量,并且不能使用此指针进行更改。

简而言之,如果您有

typedef int A[4];

然后

const A a = { 1, 2, 3, 4 };

相当于

const int a[4] = { 1, 2, 3, 4 };

如果你有

typedef int *P;

然后

const P p = new int[4]{ 1, 2, 3, 4 };

相当于

int * const p = new int[4]{ 1, 2, 3, 4 };

考虑到如果您有这样的声明

const int *p;

然后,您不需要初始化指针,因为它不是常量。

虽然当你有这样的声明

int * const p = new int;

或喜欢

const int * const p = new int; 

您应该初始化指针,因为它是一个常量。否则,编译器将发出错误。

我一遍又一遍地搜索 cpp偏好,最终找到了答案......

http://en.cppreference.com/w/cpp/language/array

据说

将 cv 限定符应用于数组类型(通过 typedef 或模板( 类型操作(将限定符应用于元素类型,但任何 元素为符合 cv 标准的数组类型被视为 具有相同的简历资格。

// arr1 and arr2 have the same const-qualified type "array of 5 const char"
typedef const char CC;
CC arr1[5] = {}; 
typedef char CA[5];
const CA arr2 = {};

这正是我所要求的!
通常
typedef const PointerType p;意味着p不能修改,但p指向的数据是可变的,typedef const Type *cp;意味着cp是可变的,但cp指向的数据是恒定的。

但是对于数组,这两种样式是等效的!

我不是 100% 确定你在问什么,但也许以下内容会有所帮助。

在第一种情况下,a[0]=0;失败,因为 a 的类型是 const int[] 。我喜欢从右到左阅读常量。

typedef int IntegerArraySz4[4];
IntegerArraySz4 const a; // constant array, assignment not allowed

在第二种情况下,指向常量整数数组的指针和指向整数数组的常量指针之间的 typedefs 存在差异。再次,从右到左:

typedef int* IntPointer;
typedef int const* ConstantIntPointer;
// This is a constant pointer to some memory
IntPointer const p = new int[4] { 1, 2, 3, 4 };
p[2] = 1; // okay
// This is a pointer to some constant memory
ConstantIntPointer cp = new int [4] { 1, 3, 4, 5 };
cp[2] = 1; // error

如果你想要一个 C 风格的数组,你需要使用一个宏:

#define A(x) int x[4]
#define CA(x) const int x[4]

这将像这样使用:

const A(a) = {1, 2, 3, 4};
CA(ca) = {1, 2, 3, 4};

但这似乎非常令人困惑。使用std::array<int, 4>似乎更可取。你可以用一个typedef来做到这一点:

typedef array<int, 4> A;
typedef const array<int, 4> CA;

这将像这样使用:

const A a = {1, 2, 3, 4};
CA ca = {1, 2, 3, 4};

请注意,代码的其余部分是非法的,因为您无法分配给const arrayconst int[]

相关文章: