C++11 中的“typedef”和“using”有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10747810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between 'typedef' and 'using' in C++11?
提问by Klaim
I know that in C++11 we can now use using
to write type alias, like typedef
s:
我知道在 C++11 中我们现在可以using
用来写类型别名,比如typedef
s:
typedef int MyInt;
Is, from what I understand, equivalent to:
是,据我所知,相当于:
using MyInt = int;
And that new syntax emerged from the effort to have a way to express "template typedef
":
而这种新的语法是为了有一种表达“ template typedef
”的方式而出现的:
template< class T > using MyType = AnotherType< T, MyAllocatorType >;
But, with the first two non-template examples, are there any other subtle differences in the standard? For example, typedef
s do aliasing in a "weak" way. That is it does not create a new type but only a new name (conversions are implicit between those names).
但是,对于前两个非模板示例,标准中是否还有其他细微的差异?例如,typedef
s 以“弱”的方式进行混叠。也就是说,它不会创建新类型,而只会创建新名称(这些名称之间的转换是隐式的)。
Is it the same with using
or does it generate a new type? Are there any differences?
它与相同using
还是生成新类型?有什么区别吗?
采纳答案by Jesse Good
They are equivalent, from the standard (emphasis mine) (7.1.3.2):
它们是等效的,来自标准(强调我的)(7.1.3.2):
A typedef-name can also be introduced by an alias-declaration. The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. It has the same semantics as if it were introduced by the typedef specifier.In particular, it does not define a new type and it shall not appear in the type-id.
typedef-name 也可以通过别名声明引入。using 关键字后面的标识符成为 typedef-name,标识符后面的可选属性说明符序列属于该 typedef-name。它与由 typedef 说明符引入的语义相同。特别是,它没有定义新的类型,也不会出现在 type-id 中。
回答by Zhongming Qu
They are largely the same, except that:
它们大致相同,除了:
The alias declaration is compatible with templates, whereas the C style typedef is not.
别名声明与模板兼容,而 C 风格的 typedef 则不兼容。
回答by 4xy
The usingsyntax has an advantage when used within templates. If you need the type abstraction, but also need to keep template parameter to be possible to be specified in future. You should write something like this.
在使用中的模板中使用时的语法有优势。如果需要类型抽象,还需要保留模板参数以便将来可以指定。你应该写这样的东西。
template <typename T> struct whatever {};
template <typename T> struct rebind
{
typedef whatever<T> type; // to make it possible to substitue the whatever in future.
};
rebind<int>::type variable;
template <typename U> struct bar { typename rebind<U>::type _var_member; }
But usingsyntax simplifies this use case.
但是使用语法简化了这个用例。
template <typename T> using my_type = whatever<T>;
my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }
回答by Validus Oculus
They are essentially the same but using
provides alias templates
which is quite useful. One good example I could find is as follows:
它们本质上是相同的,但using
提供了alias templates
非常有用的功能。我能找到的一个很好的例子如下:
namespace std {
template<typename T> using add_const_t = typename add_const<T>::type;
}
So, we can use std::add_const_t<T>
instead of typename std::add_const<T>::type
所以,我们可以使用std::add_const_t<T>
代替typename std::add_const<T>::type
回答by RoboticForest
I know the original poster has a great answer, but for anyone stumbling on this thread like I have there's an important note from the proposalthat I think adds something of value to the discussion here, particularly to concerns in the comments about if the typedef
keyword is going to be marked as deprecated in the future, or removed for being redundant/old:
我知道原始海报有一个很好的答案,但是对于像我这样在这个线程上磕磕绊绊的人来说,提案中有一个重要的说明,我认为它为这里的讨论增加了一些价值,尤其是评论中关于typedef
关键字是否为将来会被标记为已弃用,或因冗余/旧而被删除:
It has been suggested to (re)use the keyword typedef ... to introduce template aliases:
template<class T> typedef std::vector<T, MyAllocator<T> > Vec;
That notation has the advantage of using a keyword already known to introduce a type alias. However, it also displays several disavantages [sic] among which the confusion of using a keyword known to introduce an alias for a type-name in a context where the alias does not designate a type, but a template;
Vec
is notan alias for a type, and should not be taken for a typedef-name. The nameVec
is a name for the familystd::vector<?, MyAllocator<?> >
– where the bullet is a placeholder for a type-name.Consequently we do not propose the “typedef” syntax.On the other hand the sentencetemplate<class T> using Vec = std::vector<T, MyAllocator<T> >;
can be read/interpreted as: from now on, I'll be using
Vec<T>
as a synonym forstd::vector<T, MyAllocator<T> >
. With that reading, the new syntax for aliasing seems reasonably logical.
有人建议(重新)使用关键字 typedef ... 来引入模板别名:
template<class T> typedef std::vector<T, MyAllocator<T> > Vec;
这种表示法的优点是使用已知的关键字来引入类型别名。然而,它也显示了几个缺点 [原文如此],其中在别名不是指定类型而是模板的上下文中使用已知的关键字为类型名称引入别名的混淆;
Vec
是不是一个类型的别名,不应该采取一个typedef名。名称Vec
是家族的名称std::vector<?, MyAllocator<?> >
——其中项目符号是类型名称的占位符。因此,我们不建议使用“typedef”语法。另一方面,句子template<class T> using Vec = std::vector<T, MyAllocator<T> >;
可以阅读/解释为:从现在开始,我将
Vec<T>
用作std::vector<T, MyAllocator<T> >
. 通过这种阅读,别名的新语法似乎合乎逻辑。
To me, this implies continued support for the typedef
keyword in C++ because it can still make code more readable and understandable.
对我来说,这意味着继续支持typedef
C++ 中的关键字,因为它仍然可以使代码更具可读性和可理解性。
Updating the using
keyword was specifically for templates, and (as was pointed out in the accepted answer) when you are working with non-templates using
and typedef
are mechanically identical, so the choice is totally up to the programmer on the grounds of readability and communication of intent.
更新using
关键字专门针对模板,并且(如已接受的答案中指出的那样)当您使用非模板using
并且typedef
在机械上相同时,因此基于可读性和意图交流的选择完全取决于程序员.
回答by marski
Both keywords are equivalent, but there are a few caveats. One is that declaring a function pointer with using T = int (*)(int, int);
is clearer than with typedef int (*T)(int, int);
. Second is that template alias form is not possible with typedef
. Third is that exposing C API would require typedef
in public headers.
这两个关键字是等效的,但有一些注意事项。一是声明函数指针 withusing T = int (*)(int, int);
比 with 更清晰typedef int (*T)(int, int);
。其次是模板别名形式不能与typedef
. 第三是公开 C API 需要typedef
在公共头文件中。