【问题标题】:How to make type alias to "a pointer to an array of const int"?如何将类型别名设为“指向 const int 数组的指针”?
【发布时间】:2014-07-05 15:43:52
【问题描述】:

我正在做关于类型别名的练习(ex3.44 C++ Primer 5th)。 下面的代码将使:

  1. 指向 const int 数组的指针的类型别名,以及

  2. 对 const int 数组的引用的类型别名

但是结果与预期不符(参见 cmets)。为什么?

int main(){

  int ia[3] = {0, 1, 2};

  typedef const int (*cpa)[3];
  cpa g = 0;                    //(gdb) ptype g: type = int (*)[3]

  typedef const int (&cra)[3];
  cra h = ia;                   //(gdb) ptype h: type = int (&)[3]

  return 0;

}

当我删除数组时,它按预期工作。见以下代码:

int main(){

  int i = 42;

  typedef const int* cp;
  cp e = &i;                    //(gdb) ptype e: type = const int *

  typedef const int& cr;
  cr f = i;                     //(gdb) ptype f: type = const int &

  return 0;
}

最后一件事,如果使用“using”关键字,如何重写别名定义?

【问题讨论】:

  • 为什么不符合您的预期?
  • @Joseph Mansfield 缺少常量
  • 这些是对的,using 使事情变得更容易,因为您不需要在混乱中使用名称。顺便说一句,您也可以在编译时检查。 const int arr[3]; static_assert(std::is_same<cpa, decltype(&arr)>::value, "");
  • @chris 但是如果使用数组,则缺少“const”
  • @user3701346,如果你的意思是static_assert,它不是一个函数,也不是一个宏,而是一个声明(static-assert-declaration)。如果您的意思是decltype,它是一个说明符。如果你的意思是std::is_same,它是一个类型特征(基本上只是一个带有value 成员的结构)。

标签: c++ arrays pointers alias typedef


【解决方案1】:

只是您的gdb 版本的输出省略了constconst 仍然很重要。我们可以用下面这个不能编译的程序来证明:

int main(){
  const int ia[3] = {0, 1, 2};

  typedef int (*cpa)[3];
  cpa g = 0;

  typedef int (&cra)[3];
  cra h = ia;

  return 0;
}

对我来说,使用 gdb 7.7,输出符合预期:

(gdb) ptype g
type = const int (*)[3]
(gdb) ptype h
type = const int (&)[3]

using重写这些typedefs:

using cpa = const int (*)[3];
using cra = const int (&)[3];

您可以看到模式只是 using identifier = 后跟缺少标识符的声明。

【讨论】:

  • Joseph,您能否分享一下您是否打开了任何“打印漂亮”选项?
  • @user3701346 如果这意味着事先做enable pretty-printer,它似乎没有效果。
  • 等等。 cpa 是类型名,怎么打印?我只做了ptype gptype h 这两个变量。
  • @user3701346 结果相同。
  • @user3701346 我认为这是在 7.4 和 7.7 版本之间修复的错误
【解决方案2】:

你对 gdb 太信任了。由于我不明白的原因,它省略了“const”。您应该以其他方式验证类型的常量性。一种方法是尝试分配给 g[0]。这会给您一个错误,其中包含如下消息:

error: incompatible types in assignment of ‘int’ to ‘const int [3]’

立即告诉您您的问题不存在。

您还可以使用 typeid 从编译器中获取类型并打印出来。在 VC++ 上,这很简单。使用 gcc,您需要对结果进行 demangle 以使其可读。下面的代码打印了 g 和 g2 的类型,带和不带 const。

#include <stdio.h>
#include <typeinfo>

#ifdef __GNUG__
#define DEMANGLE
#endif

#ifdef DEMANGLE
#include <cxxabi.h>
#endif

template <typename T>
const char* TypeName(const T& type)
{
#ifdef DEMANGLE
    int status = 0;
    // Convert the cryptic gcc name decorations to something
    // human readable.
    return abi::__cxa_demangle(typeid(type).name(), NULL, NULL, &status);
#else
    return typeid(type).name();
#endif
}

int main(){

  int ia[3] = {0, 1, 2};

  typedef const int (*cpa)[3];
  cpa g = 0;                    //(gdb) ptype g: type = int (*)[3]
  typedef int (*cpa2)[3];
  cpa2 g2 = 0;                    //(gdb) ptype g: type = int (*)[3]

  typedef const int (&cra)[3];
  cra h = ia;                   //(gdb) ptype h: type = int (&)[3]

  printf("Type of 'g' is '%s'\n", TypeName(g));
  printf("Type of 'g2' is '%s'\n", TypeName(g2));

  //g[0] = 2; This fails to compile, thus proving that cpa/g have the correct type.

  return 0;

}

【讨论】:

  • 感谢您的提示。现在我有了另一种类型检查的方法。
猜你喜欢
  • 2015-09-10
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多