【问题标题】:No copy constructor available or copy constructor is declared 'explicit'没有可用的复制构造函数或复制构造函数被声明为“显式”
【发布时间】:2010-08-06 00:04:39
【问题描述】:

有人能解释一下为什么我在这里遇到编译错误 - 错误 C2558: class 'std::auto_ptr<_ty>' : 没有可用的复制构造函数或复制构造函数被声明为 'explicit'

#include <memory>
#include <vector>
#include <string>
template<typename T>
struct test
{
    typedef std::auto_ptr<T> dataptr;
    typedef std::auto_ptr< test<T> > testptr;
    test( const T& data ):
    data_( new T(data) )
    {
    };
    void add_other( const T& other )
    {
        others_.push_back( testptr( new test(other) ) );
    }
private:
    dataptr data_;
    std::vector< testptr > others_;
};

int main(int argc, char* argv[])
{
    test<std::string> g("d");

    //this is the line that causes the error.
    g.add_other("d");

    return 0;
}

【问题讨论】:

  • 好久没做C++了,不应该是g = test&lt;std::string&gt;("d");吗?
  • @Jesse J:两者都可以。这两种方式的行为略有不同,除了最邪恶的情况外,所有情况下都给出相同的结果。从技术上讲,您的方法将创建一个测试类,然后将其分配给 g,而不仅仅是初始化 g 本身。只有当您有自定义复制/分配/初始化行为时,这才会成为问题。
  • 谢谢大家。真正翔实的答案。

标签: c++ compiler-errors cautoptr


【解决方案1】:

基本上std::auto_ptr不能这样使用。

others_.push_back( testptr( new test(other) ) );

要求存在接受const&amp; 的复制构造函数,并且不存在std::auto_ptr 的此类构造函数。这被广泛认为是好事,因为你不应该在容器中使用std::auto_ptr如果你不明白这是为什么,那么read this article by Herb Sutter,尤其是标题为“不该做的事,以及为什么不做”的部分大约进行了 3/4。

【讨论】:

  • 如果标准容器被强制使用swap 来复制东西,auto_ptr 就可以了。我真的希望他们是。在 C++0x 中,::std::unique_ptr(很像::std::auto_ptr)也没有复制构造函数,只有一个移动构造函数,并且标准容器被强制使用移动构造函数来移动它们的内容,因此您可以将::std::unique_ptr 存储在其中并使其按预期工作。
  • 事实上,在容器中使用auto_ptr 是非法的,因为STL 容器要求其成员具有“正常”的复制行为。 Auto_ptr 不满足该要求。
  • @Omnifarious:您将 shared_ptr 与 unique_ptr 混合在一起。 Shared_ptr 是一个引用计数的智能指针,而不是具有移动语义的指针。
  • @Billy - 如果你这样做,代码警察会来把你带走,还是只会导致编译器错误?哦!你是对的shared_ptr。我现在就解决这个问题。
  • @Omnifarious:假定是编译时错误。但并非所有编译器都这样做。对于不是编译时错误的编译器,它是未定义的行为。即使这些容器有基于swap 之类的内脏,你也无法做到这一点,因为标准算法仍然会搞砸(他们希望能够不受惩罚地复制)
【解决方案2】:
    others_.push_back( testptr( new test(other) ) );

您正在尝试将 auto_ptr 推送到 std::vector

auto_ptr 没有定义隐式复制构造函数,并且不兼容作为 stl 容器类中的值。

有关更多信息,请参阅此问题:StackOverflow: Why is it wrong to use stdauto ptr with stl containers

【讨论】:

    【解决方案3】:

    您无法创建 auto_ptr 的标准库容器,就像您在此处尝试做的那样:

    std::vector< testptr > others_;
    

    因为它们没有正确的语义。您将不得不使用普通指针或不同风格的智能指针,例如shared_ptr

    【讨论】:

      【解决方案4】:

      您可能需要即将推出的 C++0x 标准中的 std::unique_ptr 或 std::shared_ptr 如果您可以访问已实现这些功能的编译器(gcc 4.5+),它将替换 auto_ptr

      http://www2.research.att.com/~bs/C++0xFAQ.html#std-unique_ptr http://www2.research.att.com/~bs/C++0xFAQ.html#std-shared_ptr

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-13
        • 2012-10-10
        • 1970-01-01
        • 2016-07-12
        • 2013-10-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多