如何实例化const typedef指针?

时间:2014-08-11 07:19:27

标签: c++ c pointers const typedef

以下代码:

typedef void* ptr_t;

void func()
{
    const ptr_t ptr; // Line 1
    ptr = ...;       // Line 2
}

产生以下编译错误:

  • 第1行,错误C2734(C ++):const对象必须初始化,如果不是extern

  • 第2行,错误C3892(C ++):您无法分配给const

  • 的变量
  • 第2行,错误C2166(C):l值指定const对象

这些编译错误背后的原因:

  • const ptr_t ptr被解释为void* const ptr而不是const void* ptr

  • 使用void* const ptr,您无法更改指针,但可以更改指向数据

  • 使用const void* ptr,您可以更改指针,但无法更改指向数据


我的目标是防止可能尝试更改ptr指向的内存内容。

我可以使用#define ptr_t void*代替typedef void* ptr_t解决此问题。

但就编码正确性而言,它并不是一个合适的解决方案。还有其他选择吗?

由于

3 个答案:

答案 0 :(得分:4)

这是一个将指针指向对象转换为指向const对象的指针的C ++解决方案:

#include <type_traits>

template <typename T>
using more_const_ptr = typename std::enable_if<
    std::is_pointer<T>::value,
    typename std::add_pointer<
        typename std::add_const<
            typename std::remove_pointer<T>::type>::type>::type>::type;

用法:

using p = int *;    // or "typedef int * p;" in C++03

int a = 10;
more_const_ptr<p> q = &a;
// *q = 20;  // Error, q is "const int *"

(在C ++ 14中,有一些有用的快捷方式可以让它更具可读性:)

template <typename T>
using more_const_ptr = std::enable_if_t<
    std::is_pointer<T>::value,
    std::add_pointer_t<std::add_const_t<std::remove_pointer_t<T>>>>;

答案 1 :(得分:3)

在第1行中,正如你所说,你有一个指针类型,然后使它成为const。这意味着您有一个指向(非常量)数据的常量指针。将其声明为type const不会解决任何问题,因为C指定此声明等同于const type

没有解决方法。通常,在typedef下隐藏指针是个坏主意。这使得代码非常难以阅读,即使您有可变命名的编码标准。只需查看Windows API,即可获得如何将C语言转换为可读性较低的完美示例。

所以快速&amp;肮脏的解决方案是通过声明typedef const void* cptr_t;来深入挖洞。或者确实使用宏,这是一个同样糟糕的解决方案。

好的解决方案是忘记隐藏在typedef背后的指针和其他将公知的C或C ++语言改为某种神秘的个人宏语言的尝试。

答案 2 :(得分:3)

#include <type_traits>
...
typedef std::remove_pointer<ptr_t>::type base_type;
typedef base_type const* const_ptr_t;

如果ptr_t实际上是模板参数而不是具体类型,那么您需要在其中抛出typename

typedef typename std::remove_pointer<ptr_t>::type base_type;