将指针 (T*) 强制转换或转换为两个常量 (T 常量 * 常量) 指针



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#变量。

  1. 得到预期的结果int *
  2. 得到预期的结果int const *
  3. 意料之中的int* const,但得到了int*const_cast是否忽视了其尾随的const论点,为什么?由于返回与参数的恒定性和类型相同,因此演员阵容是否运行过?
  4. 意料之中的int const * const,但得到了int const*const_cast是否忽视了其尾随const论点,为什么?
  5. 我想看看const_cast<int const * const>是否会在结果中包含尾随const,因为该参数a4已经具有领先const。预期int const * const .得int const*了.const_cast是否忽略了其尾随const论点,为什么?
  6. 预期int const * const .得int const*了.为什么显式强制转换仍然会排除尾随const
  7. 预期int const * const .得int const*.为什么static_cast会排除尾随const
  8. 预期int const * const .得int const*了.为什么reinterpret_cast会排除尾随const
  9. 预期int const * const .得int const*.为什么对函数int const * const返回的初始化仍然会排除结果中的尾随const
  10. 预期int const * const .从控制台输出获取int const*,但不从调试器获取。 a10被明确声明为 int const * const,那么为什么typeid().name()排除尾随常量呢? operator==产生1,那么为什么typeid()本身(不仅仅是名称(等同于a10 a4呢?VC11 调试器将a10的类型列为 int const * const 。为什么它与typeid()typeid().name()的那个不同?哪一个是正确的?
  11. 变量名称a11省略,因为它看起来像单词"all"。
  12. 我希望a12 int const * const,因为它被初始化为 a10 ,这被明确声明为 int const * constoperator==产量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;

变量abint类型,而不是const int,并且可以修改。

最新更新