【问题标题】:Why won't this code compile?为什么这段代码不能编译?
【发布时间】:2012-07-06 17:21:58
【问题描述】:

使用const,如注释所示,msvc 11 和 g++ 4.7.0 拒绝编译这个:

#include <memory>       // std::unique_ptr
#include <utility>      // std::move
using namespace std;

struct CommandLineArgs
{
    typedef unique_ptr<
        wchar_t const* const [],
        void(*)( wchar_t const* const* )
        > PointerArray;

    //PointerArray const  args;         // Oops
    PointerArray        args;
    int const           count;

    static wchar_t const* const* parsed(
        wchar_t const       commandLine[],
        int&                count
        )
    {
        return 0;
    }

    static void deallocate( wchar_t const* const* const p )
    {
    }

    CommandLineArgs(
        wchar_t const   commandLine[]   = L"",
        int             _               = 0
        )
        : args( parsed( commandLine, _ ), &deallocate )
        , count( _ )
    {}

    CommandLineArgs( CommandLineArgs&& other )
        : args( move( other.args ) )
        , count( move( other.count ) )
    {}
};

int main()
{}

错误消息似乎不是特别有用,但这里是 g++ 的输出:

main.cpp:在构造函数“CommandLineArgs::CommandLineArgs(CommandLineArgs&&)”中: main.cpp:38:38:错误:使用已删除的函数 'std::unique_ptr::unique_ptr(const std::unique_ptr&) [w i _Tp = 常量 wchar_t* 常量; _Dp = void (*)(const wchar_t* const*); std::unique_ptr = std::unique_ptr]' 在 c:\program files (x86)\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/memory:86:0 包含的文件中, 来自 main.cpp:1: c:\program files (x86)\mingw\bin\../lib/gcc/mingw32/4.7.0/include/c++/bits/unique_ptr.h:402:7: 错误:在此声明

为什么?

【问题讨论】:

  • -1,OP 没有努力使其成为 SSCE,如果 CommandLineArgs 仅包含 const 成员和移动 ctor,那么问题将很明显。
  • @Abyx:我在聊天中告诉过你,你不必提交更多证据。够了。请让它休息:它伤害了我(代表你)。好的,为您解释:当类仅包含 const 成员时会产生错误消息。如果有的话,这能告诉你什么?
  • 这是一个 SSCE - ideone.com/VOlcA ,编译器错误清楚地说明了那里出了什么问题。
  • @Abyx:您的观点似乎是,不同的代码会产生不同的错误消息,那么不同的问题就不值得问了。我同意。
  • 实际上是相同的代码,减少到错误消息更清晰的程度。只有有意义的行,std::move 替换为它的(预期的)实现。然后我们看到这样的std::move 不能在那里使用,我们明白为什么它会退回到复制。

标签: c++ constructor constants move-semantics


【解决方案1】:

没有具有签名的副本 c-tor unique_ptr(const unique_ptr&);

【讨论】:

  • 这就是错误消息所说的,是的;我的问题是为什么。
【解决方案2】:

你不能移动 const 对象。错误是因为您的移动构造函数。

unique_ptr,已删除复制构造函数和移动构造函数声明为:

unique_ptr( const unique_ptr & other );
unique_ptr( unique_ptr && other );

由于你的 unique_ptr 被声明为 const,它选择复制构造函数,而不是移动构造函数。

【讨论】:

  • 我在标准中看不到任何要求 如何 实现阻止 unique_ptr 成为 CopyConstructible 的内容,只是声明它不是 CopyConstructible。那么删除的副本ctor是(a)实现细节,(b)满足标准要求的唯一方法,(c)标准中明确要求但我错过了吗?实现是否符合(例如)声明为私有但未定义的复制 ctor?
  • @Cheersandhth.-Alf: other.args 在我看来边缘有点 const。
  • 是的,我认为实际上 const 成员的 const-ness 胜过移动后状态的 unspecified-ness。
  • @SteveJessop 也许我不明白你的问题,但 [unique.ptr]/5 告诉Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
  • @BЈовић:这就是我找到的一点。我的问题是,“除了删除复制ctor之外,还有什么方法可以满足 unique_ptr 不是 CopyConstructible 的要求?”。如果是这样,那么我认为将其留给实现有点奇怪。如果不是,那么我认为unique_ptr 有一个必须声明的构造函数(尽管声明已删除)有点奇怪,但它没有在标准中类的定义中的“构造函数”下列出。
猜你喜欢
  • 2010-10-24
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多