typedef 和 using 有什么区别?

15

使用什么方法之间有哪些区别:

typedef Some::Nested::Namespace::TypeName TypeName;
或者
using Some::Nested::Namespace::TypeName;

如何在本地作用域中提供简写的TypeName

3个回答

6

它们有不同的起源和用途。


typedef 源自于 C:回忆一下在 C 语言中声明结构体的方式:

typedef struct _MyStruct { .... } MyStruct;

它允许你仅为类型引入别名。它可以用于函数的类型,但语法有点笨拙...

typedef void (*Func)(Foo, Bar);

这里的Func现在是一个函数指针,它通过拷贝两个参数(分别是FooBar类型)并返回无类型。


using原本有着不同的含义。它的作用是将名称注入到作用域中。可以注入任何名称(几乎),包括类型、函数、变量(但不包括枚举值...)

在C++11中,语法已经得到了改进,允许使用模板别名:

template <typename T>
using equiv_map = std::map<T,T>;

这次强化的 using 意味着现在可以进行别名设置(参见下文),除了之前的功能。


C++11 的这个改变清晰地朝着语法协调方向发展。请注意别名定义现在类似于变量定义:

<name> = <expression>;

不幸的是,标准似乎将这种别名情况保留给了模板情况,因此目前typedefusing共存,各自有自己的寻找对象。

抱歉,由于技术术语的限制,无法进行更加通俗易懂的翻译。

您的最后一段是指 using name = int; 在C++11中不符合语法要求吗? - dyp
@DyP:这就是我的意思,尽管我不记得为什么,因为它确实起作用(对于函数引用/指针非常方便)。我想知道是否被早期版本的gcc / clang所影响。 - Matthieu M.

6

typedef 为类型提供了别名。

typedef Some::Nested::Namespace::TypeName TypeName;

一旦这样做,您可以在本地命名空间中通过 TypeName 来引用 Some::Nested::Namespace::TypeName


using declaration 可以使该类型在当前命名空间中可见。

using Some::Nested::Namespace::TypeName;

将该类型导入到当前命名空间中。

在这种情况下,使用上述任意一种方法,您都可以在本地命名空间中仅使用 TypeName 来引用 Some::Nested::Namespace::TypeName


2
有实质性的区别吗?特别是在考虑到增强的C++11 using语句,它允许定义模板别名时。 - Konrad Rudolph
至少有一个模板类型的区别。你只能typedef一个特定的类型,比如vector<int>,而你只能在未经专门化的模板上使用using(例如vector)。 - jalf
如果你有一堆想要导入的重载运算符,typedef 在这种情况下不起作用,因为你必须使用 using - Khaled Alshaya
@AraK:typedef仅用于别名类型(顾名思义),因此它当然无法用于导入其他任何内容。 - Matthieu M.

6

使用using只是将声明带入了本地作用域,而typedef引入了一个typedef-name。它们之间的一个区别是精细化类型说明符,例如:


namespace n
{
  class foo
  {
  };
}
typedef n::foo n_foo; using n::foo;
int main() { class foo f1; // ok,声明变量f1的类型为n::foo。 class n_foo f2; // error,不可以在精细化类型说明符中使用typedef-name。 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接