typedef 一个包含 const 元素的数组,使用 const ArrayType 或 c++ 中的 ConstAr
typedef an array with const elements using const ArrayType or ConstArrayType in c++
我将定义一些具有固定大小和常量元素的数组。
我尝试使用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 array
或const int[]
。
- 使用对const结构的const数组的引用进行构造
- 使用 std::string () const 函数启动线程或未来
- 在运算符重载定义中使用成员函数(const错误)
- 使用共享指针的函数调用,其对象应为 const
- 为什么 GCC 在使用类型别名时处理 const reinterpret_cast不同?
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 在函数中使用 const int size 参数创建数组会在 Visual Studio 中抛出错误 C++:表达式的计
- 使用 fopen 打开 .pak 文件并使该文件应用于 const 无符号字符* (C++)
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- 类型为 "Bucket&"(未限定的 const 限定)的引用不能使用 "SortedList." 类型的值进行初始化 如何修复此错误?
- 在 constexpr 构造函数 (c++17) 中赋值到 const char * 在使用 Android NDK 时
- 如果我在 const 函数上使用指针,我可以返回什么?
- 将 const 转换为 const char* 无效,我该如何解决?使用 gcc7 时失败
- 当设置为 const 变量时使用 nullptr
- 何时应在构造函数参数中使用 const C++?
- 使用 const char* 键映射 C++ 检索空值
- 无法使用类型 'const char *' 的左值初始化类型 'char *' 的成员子对象
- 在其他容器中使用 boost::container::static_vector 时,GCC 编译错误"将'const s'绑定到类型's&'的引用丢弃限定符"
- c++模板和const(使用auto在没有编译器警告的情况下发生冲突)
- 使'const'使用类型特征的结果