C++0X 中的 auto 和 decltype 之间的区别

difference between auto and decltype in c++0x

本文关键字:之间 区别 decltype 中的 auto C++0X      更新时间:2023-10-16

我在使用自动和 decltype 时遇到了问题。

void f(const vector<int>& a, vector<float>& b)
{
    typedef decltype(a[0]*b[0]) Tmp;
    for (int i=0; i < b.size(); ++i) {
      auto p0 = new auto(a[i]*b[i]);
      auto p1 = new decltype(a[i]*b[i]);
      *p0=a[i]*b[i];
      *p1=a[i]*b[i];
      cout<<*p0<<endl;
      cout<<*p1<<endl;
      delete p0;
      delete p1;
   }
}
 int main()
{
    vector<float>vec2;
    vec2.push_back(2.0);
    vector<int>vec1;
    vec1.push_back(5);
    return 0;
}

上面的代码在GCC4.7中运行良好。我可以使用"new auto(a[0]*b[0])"为 a[0]*b[0]的类型分配内存吗?在这种情况下,我无法区分 decltype 和 auto 之间的区别。

区别在于:

  new auto(a[i]*b[i]);

正在分配a[i]*b[i]任何类型的对象,并使用该值初始化该对象。也就是说,括号是初始值设定项。而使用 decltype:

  new decltype(a[i]*b[i]);

分配相同类型的对象,但没有初始值设定项。对象默认初始化。

基本上,decltype(...)被视为类型,而auto指定要从初始化器推断的类型。


C++11 风格

由于除非在特殊情况下,否则不应使用new,如果出于某种原因需要这些语义,它们应该正确编写如下:

template<typename T, typename... Args> T make_unique(Args &&...args) {
  return std::unique_ptr<T>{std::forward<Args>(args)...};
}
template<typename T> T make_unique_auto(T &&t) {
    return std::unique_ptr<T>{std::forward<T>(t)};
}
// new auto(a[i]*b[i])
auto p1 = make_unique_auto(a[i]*b[i]);
// new decltype(a[i]*b[i])
auto p2 = make_unique<decltype(a[i]*b[i])>();

此外,如果习惯于普遍使用 C++11 统一初始化,并且如果停止使用括号进行初始化,那么最终与 decltype 一起使用的括号在程序员看来将不再像初始值设定项一样。

出于这个原因和其他原因,我认为"现代"C++11 样式最好包含一条规则,即应始终使用大括号,切勿使用括号进行初始化。(以及除非带括号外不能调用的构造函数,例如 std::vector<int>(int,int);,应避免;不要创建新的,也不要使用旧的。