将指针(T *)转换或转换为两个const(T const * const)指针

时间:2013-10-13 02:49:20

标签: c++ casting auto const-correctness const-cast

C ++

我想知道一个指针是否已经是两个const指针(例如T const * const)可以隐式或显式地转换,通过某些东西(例如函数)处理,或者以其他方式处理转换为生成T const * const,在用于初始化声明为T const * const的变量之前或之前。我怎么能这样做?

我认为如果我开始使用T*,那么一个const_cast(或两个,如果演员阵容一次只能投放一个const)就足够了,但是显然它没有。代码中的许多变量显示通过转换或从函数返回而产生T const * const的不同尝试。每个演员都无法返回一个尾随const的指针。 (我将const左侧的*称为前导const,将*右侧的const称为尾随const。)在不成功的演员阵容中,我尝试通过直接初始化强制VC11失败。这是在typeid(/*...*/).name()编译的。 g++ on stack-crooked.com提供逻辑上等效的控制台输出,虽然#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 *变量。

  1. 得到预期结果int const *
  2. 得到预期结果int* const
  3. 预计int*,但得到const_castconst是否忽略了它的尾随int const * const参数以及为什么?由于返回与参数的const和类型相同,所以转换是否完全运行?
  4. 预计int const*,但得到const_castconst是否忽略了它的尾随const_cast<int const * const>参数以及为什么?
  5. 我想看看const是否会在结果中包含尾随a4,因为参数const已经有一个前导int const * const。预期int const*。得到const_castconst是否忽略了它的尾随int const * const参数以及为什么?
  6. 预计int const*。得到const。为什么显式转换仍会排除尾随int const * const
  7. 预计int const*。得到static_cast。为什么const会排除尾随int const * const
  8. 预计int const*。得到reinterpret_cast。为什么const会排除尾随int const * const
  9. 预计int const*。得到int const * const。为什么函数const返回的初始化仍会排除结果中的尾随int const * const
  10. 预计int const*。从控制台输出获得a10但未从调试器获得。 int const * const显式声明为typeid().name(),那么为什么operator==会排除尾随的const? 1会产生typeid(),那么为什么a10本身(不仅仅是a4的名称)等同于a10的{​​{1}}? VC11调试器将int const * const的类型列为typeid()。为什么它与typeid().name()a11的不同?哪一个是正确的?
  11. 变量名a12被省略,因为它看起来像单词“all”。
  12. 我希望int const * consta10,因为它已初始化为int const * const,已明确声明为operator==1会产生typeid(),因此int const*仍为int const*。从控制台输出和调试器获得const。为什么它们与预期结果不同?
  13. 所有演员表,函数返回和初始化是否仅限于一次仅在一个const中投射?领先的{{1}}是他们唯一能投入的吗?

1 个答案:

答案 0 :(得分:3)

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;

变量ab属于int类型,而不是const int,可以修改。