将指针 (T*) 强制转换或转换为两个常量 (T 常量 * 常量) 指针
Cast or convert a pointer (T*) to a two-const (T const * const) pointer
C++
我想知道一个指针是否还不是两const
指针(例如 T const * const
(可以隐式或显式地强制转换,通过某些东西(例如函数(处理,或以其他方式转换,以产生T const * const
,而无需或之前用于初始化声明为T const * const
的变量。我该怎么做?
我认为如果我从T*
开始,那么一个const_cast
(或两个,以防演员一次只能投const
(就足够了,但显然并非如此。代码中的许多变量显示了通过强制转换或从函数返回来生成T const * const
的不同失败尝试。每个强制转换都无法返回带有尾随const
的指针。(我将*
左侧的const
称为前导const
,将*
右侧的const
称为尾随。由于转换不成功,我尝试通过直接初始化强制const
,但没有成功。这是在VC11
年编译的。stack-crooked.com 上的 G++ 给出了逻辑上等效的控制台输出,尽管typeid(/*...*/).name()
的名称不同。
#include <iostream>
#include <typeinfo>
using namespace std;
int const * const foo()
{
return nullptr;
}
int main()
{
int x = 7;
auto a1 = &x;
cout << typeid(a1).name() << endl;
auto a2 = const_cast<int const *>(&x);
cout << typeid(a2).name() << endl;
auto a3 = const_cast<int * const>(&x);
cout << typeid(a3).name() << endl;
auto a4 = const_cast<int const * const>(&x);
cout << typeid(a4).name() << endl;
auto a5 = const_cast<int const * const>(a4);
cout << typeid(a5).name() << endl;
auto a6 = (int const * const) &x;
cout << typeid(a6).name() << endl;
auto a7 = static_cast<int const * const>(a4);
cout << typeid(a7).name() << endl;
auto a8 = reinterpret_cast<int const * const>(a4);
cout << typeid(a8).name() << endl;
auto a9 = foo();
cout << typeid(a9).name() << endl;
int const * const a10 = &x;
cout << typeid(a10).name() << endl;
cout << ( typeid(a10) == typeid(a4) ) << endl;
auto a12 = a10;
cout << typeid(a12).name() << endl;
cout << ( typeid(a12) == typeid(a4) ) << endl;
}
预期结果与实际结果以及问题:
问题编号对应于相同编号的a#
变量。
- 得到预期的结果
int *
- 得到预期的结果
int const *
- 意料之中的
int* const
,但得到了int*
。const_cast
是否忽视了其尾随的const
论点,为什么?由于返回与参数的恒定性和类型相同,因此演员阵容是否运行过? - 意料之中的
int const * const
,但得到了int const*
。const_cast
是否忽视了其尾随const
论点,为什么? - 我想看看
const_cast<int const * const>
是否会在结果中包含尾随const
,因为该参数a4
已经具有领先const
。预期int const * const
.得int const*
了.const_cast
是否忽略了其尾随const
论点,为什么? - 预期
int const * const
.得int const*
了.为什么显式强制转换仍然会排除尾随const
? - 预期
int const * const
.得int const*
.为什么static_cast
会排除尾随const
? - 预期
int const * const
.得int const*
了.为什么reinterpret_cast
会排除尾随const
? - 预期
int const * const
.得int const*
.为什么对函数int const * const
返回的初始化仍然会排除结果中的尾随const
? - 预期
int const * const
.从控制台输出获取int const*
,但不从调试器获取。a10
被明确声明为int const * const
,那么为什么typeid().name()
排除尾随常量呢?operator==
产生1
,那么为什么typeid()
本身(不仅仅是名称(等同于a10
a4
呢?VC11 调试器将a10
的类型列为int const * const
。为什么它与typeid()
和typeid().name()
的那个不同?哪一个是正确的? - 变量名称
a11
省略,因为它看起来像单词"all"。 - 我希望
a12
int const * const
,因为它被初始化为a10
,这被明确声明为int const * const
。operator==
产量1
,所以typeid()
仍然int const*
。从控制台输出和调试器获取int const*
。为什么它们与预期结果不同?
是否所有强制转换、函数返回和初始化都仅限于一次只转换一个const
?领先的const
是他们唯一可以投进去的东西吗?
const_cast
确实按照您认为的方式工作。但是,auto
并没有按照您的想法进行操作。 auto
的工作方式类似于函数模板参数推导(实际上,它是根据后者定义的(。现在考虑:
template<typename T>
void f(T x);
f(42);
int const n = 42;
f(n);
这两个调用都是为了f<int>()
,而不是f<const int>()
。顶级 const 修饰符被模板参数推导忽略。出于同样的原因,在此示例中
auto a = 42; a = 84;
auto b = n; b = 84;
变量a
和b
是int
类型,而不是const int
,并且可以修改。
- 为什么下面带有非常量转换函数的代码没有歧义?
- 如何将变量内容常量转换为 std::array 的大小?
- 将结构C++成员从非常量转换为常量
- 意外 (IMO) 常量转换警告
- 警告:ISO C++禁止将字符串常量转换为'char*' [-Wwrite-strings]
- 为什么无法将常量 X 转换为 X &?
- 重载常量和非常量转换运算符返回数组类型时出现 MSVC 错误 C2593
- 将字符串常量转换为char
- 警告:ISO C++禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- 错误C2662无法从常量转换为引用
- 常量转换运算符的行为
- 如何在 C 中将多字符常量转换为整数
- 从字符串常量转换,c++ 中的指针
- 从字符串常量转换为字符*
- 在这里做常量转换安全吗
- boost序列化错误C4308:负整数常量转换为无符号类型
- 不赞成从字符串常量转换为“char*”[-Wwrite strings]
- C++非常量到常量转换编译错误
- C++-不赞成在第三方标头中从字符串常量转换为“char*”
- 空指针常量转换为右值