我知道在c++ 11中,我们现在可以使用using来编写类型别名,比如typedefs:

typedef int MyInt;

在我看来,相当于:

using MyInt = int;

新语法的出现是为了有一种表达“template typedef”的方法:

template< class T > using MyType = AnotherType< T, MyAllocatorType >;

但是,对于前两个非模板示例,标准中还有其他细微的差异吗?例如,typedef以一种“弱”的方式进行混叠。也就是说,它不创建新类型,而只创建新名称(这些名称之间的转换是隐式的)。

它和使用是一样的还是生成一个新的类型?有什么不同吗?


当前回答

它们本质上是相同的,但使用别名模板是非常有用的。我能找到的一个很好的例子如下:

namespace std {
 template<typename T> using add_const_t = typename add_const<T>::type;
}

因此,我们可以使用std::add_const_t<T>来代替typename std::add_const<T>::type

其他回答

到目前为止,c++ 23将typedef和using更紧密地结合在一起:P2360建议使用构成初始化语句,例如@dfrib的回答中列出的那些作为error: expected表达式。

然而,即使使用P2360,类型定义也不能是模板。

(编辑[2022-09-14]:信息不正确。)

总的来说,using严格来说比typedef更强大,而且在我看来可读性也更好。

它们在很大程度上是相同的,除了:

别名声明与模板兼容,而C 样式typedef则不是。

它们本质上是相同的,但使用别名模板是非常有用的。我能找到的一个很好的例子如下:

namespace std {
 template<typename T> using add_const_t = typename add_const<T>::type;
}

因此,我们可以使用std::add_const_t<T>来代替typename std::add_const<T>::type

using语法在模板中使用时具有优势。如果需要类型抽象,还需要保留模板参数以便将来可以指定。你应该这样写。

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; }

但是使用语法简化了这个用例。

template <typename T> using my_type = whatever<T>;

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }

它们是等价的,从标准(强调我的)(7.1.3.2):

typef -name也可以通过别名声明引入。的 using关键字后面的标识符变成了typedef-name,而 可选的属性说明符-seq跟在标识符后面 到那个typef -name。它有相同的语义,就好像它是 由typedef说明符引入。特别是,它 没有定义新类型,并且它不应该出现在type-id中。