简体   繁体   English

在c ++中使用const ArrayType或ConstArrayType在一个数组中使用const元素

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

I am going to define some arrays with fixed size and const elements. 我将定义一些具有固定大小和const元素的数组。
I tried to use typedef , but there seems to be something confused: 我试图使用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;

All assignments will cause syntax error in the code above which I think a[0] = 0; 所有赋值都会导致上面代码中的语法错误,我认为a[0] = 0; should be legal before my test. 我的考试前应该是合法的。

Considering pointers, 考虑指针,
the result is much easier to understand that p[0] = 0; 结果更容易理解p[0] = 0; and cp = p; cp = p; is correct. 是正确的。

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;

Why does the cv-qualifier behave different on pointer and array? 为什么cv-qualifier在指针和数组上表现不同?
Is it because the array has already been a const pointer, then the compiler makes some implicit conversion? 是因为数组已经是一个const指针,那么编译器会进行一些隐式转换吗?

PS I compiled the code on Visual Studio 2013. PS我在Visual Studio 2013上编译了代码。

These two declarations 这两个声明

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

are fully equivalent and declare constant arrays. 完全等效并声明常量数组。 If you will run this simple program (for example using MS VC++) 如果你将运行这个简单的程序(例如使用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;
}

you will get the same result for the both output statements 你将得到两个输出语句相同的结果

int const [4]
int const [4]

In fact you could write instead 实际上你可以改写

#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;
}

with the same result. 结果相同。

As for pointer declarators then the semantic has a minor difference. 至于指针声明符,那么语义有一个小的区别。 You may use cv-qualifiers with pointer declarators 您可以将cv-qualifiers与指针声明符一起使用

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

That is you may write for example 那就是你可以写一些例子

typedef const int * const P;

(constant pointer that points to constant data). (指向常量数据的常量指针)。

Thus if you will write 因此,如果你会写

typedef int *P;

and then write 然后写

typedef const P CP;

when CP will be a constant pointer. CP将是一个常量指针。 The object it points to is not constant. 它指向的对象不是恒定的。 Only the pointer itself is constant and may not be changed. 只有指针本身是常量,可能不会更改。 That is declaration 那是宣言

typedef const P CP;

is equivalent to 相当于

typedef int * const CP;

It is not the same as 它不一样

typedef const int *CP;

where in the last declaration the pointer itself is not constant. 在最后一个声明中,指针本身不是常量。 It is the object pointed to by a pointer having this type will be constant and may not be changed using this pointer. 指针指向的对象具有此类型将是常量,并且可能无法使用此指针进行更改。

Shortly speaking if you have 如果你有的话,简短地说

typedef int A[4];

then 然后

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

is equivalent to 相当于

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

If you have 如果你有

typedef int *P;

then 然后

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

is equivalent to 相当于

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

Take into account that if you have declaration like 考虑到如果你有声明就好了

const int *p;

then you need not to initialize the pointer because it is not constant. 那么你不需要初始化指针,因为它不是常量。

While when you have declaration like 而当你有声明时

int * const p = new int;

or like 或者喜欢

const int * const p = new int; 

you shall initialize the pointer because it is a constant. 你应该初始化指针,因为它是一个常量。 Otherwise the compiler will issue an error. 否则编译器将发出错误。

I searched cppreference again and again and finially found the answer... 我一次又一次地搜索了cppreference并最终找到答案......

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

It is said that 有人说

Applying cv-qualifiers to an array type (through typedef or template type manipulation) applies the qualifiers to the element type, but any array type whose elements are of cv-qualified type is considered to have the same cv-qualification. 将cv限定符应用于数组类型(通过typedef或模板类型操作)将限定符应用于元素类型,但任何其元素具有cv限定类型的数组类型都被视为具有相同的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 = {}; 

which is exactly what I am asking for! 这正是我要求的!
Usually, 通常情况下,
typedef const PointerType p; means that p can not be modified but the data pointed by p is mutable, and typedef const Type *cp; 意味着p不能修改,但p指向的数据是可变的,并且typedef const Type *cp; means cp is mutable but the data pointed by cp is constant. 表示cp是可变的,但cp指向的数据是常量。

But for an array, these two styles are equivalent! 但是对于一个数组,这两种风格是等价的!

I'm not 100% sure what you're asking, but maybe the following will be helpful. 我不是100%肯定你在问什么,但也许以下内容会有所帮助。

In the first case, a[0]=0; 在第一种情况下, a[0]=0; fails because the type of a is const int[] . 失败,因为a的类型是const int[] I like reading const from right to left. 我喜欢从右到左阅读const。

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

In the second case, there is a difference in your typedefs between a pointer to a constant integer array and a constant pointer to an integer array. 在第二种情况下,在指向常量整数数组的指针和指向整数数组的常量指针之间,typedef存在差异。 Again, from right to left: 再次,从右到左:

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

It you want a C-style array you'll need to use a macro: 你需要一个C风格的数组,你需要使用一个宏:

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

Which would be used like: 将使用如下:

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

But that appears very confusing. 但这看起来很混乱。 Using std::array<int, 4> seems by far preferable. 使用std::array<int, 4>似乎是最好的。 And you could do that with a typedef : 你可以用typedef做到这一点:

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

Which would be used like: 将使用如下:

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

Note that the remainder of your code is illegal since you cannot assign to a const array or a const int[] . 请注意,您的代码的其余部分是非法的,因为您无法分配给const arrayconst int[]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM