【问题标题】:difference between auto and decltype in c++0xc++0x中auto和decltype的区别
【发布时间】:2012-06-07 15:21:57
【问题描述】:

我在使用 auto 和 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 之间的区别。

【问题讨论】:

    标签: c++ c++11 auto decltype


    【解决方案1】:

    不同之处在于:

      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&lt;int&gt;(int,int);;不要创建新的构造函数,也不要使用旧的构造函数。)

    【讨论】:

    • 也就是说第一个和new decltype(a[i]*b[i])(a[i]*b[i]);一样。
    • 我心里突然有点想哭。我希望永远看到那个。
    • 不会new auto {a[i]*b[i]}; 分配std::initializer_list 吗? cin auto c = {a[i]*b[i]}; 的类型是 std::initializer_list
    • @Kleist Aww,我忘记了。这条规则对我来说似乎不是第一次不幸。尽管在这种情况下,它既好又坏;明确禁止使用带有autonew 的统一初始化,但幸运的是C++11(以及C++14)风格根本不允许使用new。如果由于某种原因需要此处要求的确切语义,则可以正确完成,例如 make_unique_auto(a[i]*b[i])make_unique&lt;decltype(a[i]*b[i])&gt;()
    猜你喜欢
    • 2021-11-18
    • 2014-02-17
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 2021-08-31
    • 2012-12-17
    相关资源
    最近更新 更多