【问题标题】:The "most important const" vs. auto_ptr: Why the code does not compile?“最重要的 const”与 auto_ptr:为什么代码无法编译?
【发布时间】:2013-11-08 20:21:06
【问题描述】:

以下代码无法在 Visual C++ 2008 和 2010 上编译:

#include <memory>

struct A {};

      std::auto_ptr<A> foo()  { return std::auto_ptr<A>(new A); }
const std::auto_ptr<A> bar()  { return std::auto_ptr<A>(new A); }

int main()
{
   const std::auto_ptr<A> & a = foo(); // most important const

   const std::auto_ptr<A> & b = bar(); // error C2558:
                                       // class 'std::auto_ptr<_Ty>' :
                                       // no copy constructor available or copy
                                       // constructor is declared 'explicit'

                                bar(); // No error?
}

我希望将“最重要的 const”应用于变量“b”,但它没有编译,并且由于某种原因,编译器要求使用复制构造函数(这让我感到惊讶,因为不应该有复制此处涉及)。对bar() 的独立调用工作正常,这意味着,我猜,这确实是b 的初始化问题。

这是编译器错误,还是标准中描述的真正编译错误?

(也许在 C++98 中被禁止,在 C++11 中被授权?)

注意:它可以在 Visual C++ 2012、gcc 4.6 和 Solaris CC(所有编译器...)上编译,但不能在 gcc 3.4 和 XL C 上编译)

【问题讨论】:

  • 你是否包含了
  • 是的,我做到了... :-) ...我会更新帖子以显示这一点。
  • @SHR 如果您打算将所有权转移给调用者,则返回auto_ptr 非常好。
  • 返回 auto_ptr 很好,因为有很多 auto_ptr_ref 诡计专门设计用于使这种事情发挥作用。
  • @ZacHowland:可能是因为如果您使用的是 VS2008、VS2010、gcc 3.4 和 xlC,std 中没有 unique_ptrauto_ptr 至少在所有这些编译器支持的 C++ 版本中是标准化的。

标签: c++ c++11 auto-ptr c++98


【解决方案1】:

在 C++03 和 C++98 中,当将 const 引用绑定到右值(例如按值返回的函数)时,实现可以将引用直接绑定到右值,也可以复制右值并将引用绑定到该副本。由于auto_ptr 的复制构造函数采用非常量引用,因此第二个选择仅在返回的右值不是const 限定的情况下才有效,但编译器仍然允许尝试这样做,即使它不起作用。

在 C++11 中,这些额外的副本是不允许的,如果不需要转换,则实现必须直接绑定到右值。

See also here.

【讨论】:

    【解决方案2】:

    至少在 C++11 之前,标准要求对象是 在这种情况下可复制。最后,语义:

    T const& t = f();
    

    ,其中f 按值返回T,是:

    T tmp = f();
    T const& t = tmp;
    

    这需要一个拷贝构造函数。

    对于std::auto_ptr,您遇到的问题 是复制构造函数被定义为采用非常量 参考,这意味着你不能复制一个临时的。一些 编译器(例如 Microsoft)不强制执行此操作,这意味着 您的代码可能适用于它们,但从根本上说是非法的。

    真正的问题是你为什么在这里使用引用。你 需要以一种或另一种方式使用局部变量;仅供参考 引入了额外的间接层。

    【讨论】:

    • 不,这不是真正的问题:这不是我的代码。我只是好奇为什么这段代码无法编译... +1 BTW ...
    猜你喜欢
    • 2015-04-06
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多