【问题标题】:Using const and decltype with a pointer variable将 const 和 decltype 与指针变量一起使用
【发布时间】:2015-04-18 23:00:25
【问题描述】:

以下代码允许我更改 *p2 的值,即使 p2 是用 const 声明的。

int *p1;

const decltype(p1) p2 = new int(100);
*p2 = 200;
cout << "*p2: " << *p2 << endl; // Outputs *p2: 200

但是,如果我使用“int *”而不是“decltype(p1)”,那么编译器会标记错误。

const int * p2 = new int(100);
*p2 = 200;
cout << "*p2: " << *p2 << endl;

error: assignment of read-only location ‘* p2’
  *p2 = 200;
      ^

我正在使用 g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2。

decltype 应用于指针变量时是否忽略 const 说明符?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    const decltype(p1) p2 表示 int* const p2 。

    这意味着你不能改变p2,但你可以改变指向的东西。


    const T 总是将 const 应用于T 的所谓“顶级”。当T 是复合类型(即从基本类型集构建的类型)时,如果您想将const 应用到较低级别,则必须跳过障碍。

    当 T 为 int * 时,添加顶级 const 将得到 int * const。 * 划分一个级别;要获取* 下方的内容,您必须手动删除*,应用const,然后将* 放回去。

    一个可能的解决方案是:

    const std::remove_pointer<decltype(p1)>::type *p2 = new int(100);
    

    【讨论】:

    • @quantdev 你是对的,我从另一个 SO 答案中复制而没有测试。还有其他解决方案吗?
    • @quantdev 有 const std::remove_reference&lt;decltype(*p1)&gt;::type *p2 = ...; 虽然有点丑
    • std::add_pointer&lt;std::add_const&lt;std::remove_pointer&lt;decltype(p1)&gt;::type&gt;::type&gt;::type p2 = new int(100); 可以工作...
    • @quantdev 我想出了一个混合...可能没必要在这里使用add_pointer 和add_const
    【解决方案2】:

    std::pointer_traits 在这里会派上用场。 std::pointer_traits::element_type 和 std::pointer_traits::rebind 允许您编写一个通用表达式,该表达式适用于任何类似指针的类型:

    using element_type = std::pointer_traits<decltype(p1)>::element_type;
    using pointer_like_to_const = std::pointer_traits<decltype(p1)>::rebind<std::add_const_t<element_type>>;
    pointer_like_to_const p2 = new int(100);
    

    请注意,即使 p1 是 shared_ptr&lt;int&gt; 或 unique_ptr&lt;int&gt;,此代码也可以工作。

    【讨论】:

      猜你喜欢
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 2014-10-08
      • 2012-11-17
      • 2021-01-07
      • 2011-07-28
      • 1970-01-01
      • 2022-11-11
      相关资源
      最近更新 更多