当我使用 typedef 或使用 int 时,它仍然是 int 多少?

Posted

技术标签:

【中文标题】当我使用 typedef 或使用 int 时,它仍然是 int 多少?【英文标题】:When I use typedef or using for an int, how much is it still an int? 【发布时间】:2015-06-04 10:49:56 【问题描述】:

我尝试了以下方法:

using Idx = int;
array<Value, N> arr;

for(Idx i = 0; i < N; i ++)
  arr[i].doSomething();

我预计当我尝试使用Idx 时编译器会发出警告或错误,就好像它是int 一样。但事实并非如此。

那么,当我使用usingtypedef 将A 类型别名为B 时,B 类型的变量是否仍然是A 类型,反之亦然?因此,当类型看起来相同但含义不同时,重命名类型无法实现类型安全。

(这与我最近问的以下问题有关:How to make types for indexing)

【问题讨论】:

这里的关键字是"alias"这个词,意思是Idx(在你的情况下)只是int的另一个名字。 【参考方案1】:

别名声明或typedef 只是为别名类型创建一个新名称。在这种情况下,Idxint 没有不同的类型;它们可以互换使用,语义上没有区别。

来自 [dcl.typedef](强调我的):

使用 typedef 说明符声明的名称成为 typedef-name。在其声明范围内,一个 typedef-name 在语法上等同于关键字,并命名与标识符关联的类型 第 8 条中描述的方式。 因此,typedef-name 是另一种类型的同义词。 typedef-name 确实 不要像类声明或枚举声明那样引入新类型。

【讨论】:

【参考方案2】:

typedef 和等效的using 语句不会增加任何类型安全性,因为它们为 same 类型引入了替代标识符。

有时希望轻松创建不同的类型,您可能会遇到这样的情况:

template <typename T, size_t Id>
struct Distinct_Type

    explicit Distinct_Type(const T& t) : t_(t)  
    const T& get() const  return t_; 
    ...whatever else...
    T t_;
;

用法如下:

typedef Distinct_Type<int, __LINE__> Age;
void f(Age);
void g()  f(Age(88)); /*forced explicit construction*/ 

显然__LINE__ 是一个令人讨厌且容易出错的 hack:使用 C++11 可以创建可靠工作的编译时间递增值,但代码太长,无法在此处重新创建和包含 - 如果有兴趣,请谷歌。

这些真正不同的类型虽然存在问题:例如,如果您调用像 template &lt;typename T&gt; void f(T t); ala f(Distinct_Type&lt;int, 1&gt;(1));f(Distinct_Type&lt;int, 2&gt;(1));f(Distinct_Type&lt;int, 3&gt;(1)); 这样的函数 - 编译器/链接器可能会或可能不会消除这三个中的两个从可执行映像中实例化,减少代码膨胀。

【讨论】:

【参考方案3】:

如果有一种从内置类型派生类的简单方法会很好,尤其是在禁用自动转换的情况下。例如,可以为英尺和米定义不同的整数类,以防止导致Mars Orbiter Crash in 1999 的错误。 Ada 专注于安全provides that feature。 another answer 中提供了在 C++ 中不可能的原因(那里的 OP 试图显式地从 int 继承):int 的 C 类型系统是如此“混乱”(Stroustrup),以至于这些类型不适合构建块在类层次结构中。

就像在 C++ 中一样,必须编写一个包装器,其中包含所有想要的操作,这些操作在 Ada 的情况下会自动提供。

【讨论】:

以上是关于当我使用 typedef 或使用 int 时,它仍然是 int 多少?的主要内容,如果未能解决你的问题,请参考以下文章

typedef和模板的未定义符号? [复制]

typedef char int8; 这样定义的好处?

指向 cv 和/或 ref 限定成员函数的指针的 typedef

SWIG typedef - Perl 数组

[C++11]使用using和typedef给模板定义别名

为啥他使用“typedef vector<double>::size_type”而不是使用“int”