std :: auto_ptr Visual Studio 6.0中的编译问题

FP.*_*FP. 2 c++ visual-studio-6

更新:编辑代码示例以使用AutoA进行解决方法(这是最初的意图).在看到rlbond的回答后意识到了这一点.

我正在尝试auto_ptr根据此线程的建议合并我的代码中的用法:

通过方法接口表达C++参数的用法

但是,在使用Visual Studio 6.0进行编译时,我收到了一些意外的编译错误.在处理std::auto_ptr派生类型的赋值/副本到std::auto_ptr基本类型的a时,它有一个问题.这是我的编译器特有的问题吗?

我知道强烈建议使用Boost,但在我的项目中它不是一个选项.如果我还想使用auto_ptr,我是否被迫使用调用方法std::auto_ptr::release()?从我到目前为止遇到的情况来看,这个问题会导致编译错误,因此很容易捕获.但是,可以采用调用release的约定来分配基类型的'auto_ptr',从而使我遇到任何维护问题吗?特别是如果使用不同的编译器构建(假设其他编译器没有这个问题).

如果release()由于我的情况导致解决方法不好,我是否应该使用不同的约定来描述所有权转移?

以下是说明该问题的示例.

#include "stdafx.h"
#include <memory>

struct A
{
    int x;
};

struct B : public A
{
    int y;
};

typedef std::auto_ptr<A> AutoA;
typedef std::auto_ptr<B> AutoB;

void sink(AutoA a)
{
    //Some Code....
}

int main(int argc, char* argv[])
{
    //Raws to auto ptr
    AutoA a_raw_to_a_auto(new A());
    AutoB b_raw_to_b_auto(new B());
    AutoA b_raw_to_a_auto(new B());

    //autos to same type autos
    AutoA a_auto_to_a_auto(a_raw_to_a_auto);
    AutoB b_auto_to_b_auto(b_raw_to_b_auto);

    //raw derive to auto base
    AutoB b_auto(new B());

    //auto derive to auto base
    AutoA b_auto_to_a_auto(b_auto);  //fails to compile

    //workaround to avoid compile error.
    AutoB b_workaround(new B());
    AutoA b_auto_to_a_auto_workaround(b_workaround.release());

    sink(a_raw_to_a_auto);
    sink(b_raw_to_b_auto);  //fails to compile

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

Compiling...
Sandbox.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Sandbox\Sandbox.cpp(40) : error C2664: '__thiscall std::auto_ptr<struct A>::std::auto_ptr<struct A>(struct A *)' : cannot convert parameter 1 from 'class std::auto_ptr<struct B>' to 'struct A *'
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
C:\Program Files\Microsoft Visual Studio\MyProjects\Sandbox\Sandbox.cpp(47) : error C2664: 'sink' : cannot convert parameter 1 from 'class std::auto_ptr<struct B>' to 'class std::auto_ptr<struct A>'
        No constructor could take the source type, or constructor overload resolution was ambiguous
Error executing cl.exe.

Sandbox.exe - 2 error(s), 0 warning(s)
Run Code Online (Sandbox Code Playgroud)

Mar*_*utz 5

第一个很简单:

AutoA b_auto_to_a_auto(b_auto);  //fails to compile
Run Code Online (Sandbox Code Playgroud)

这在VC6上失败,因为它需要成员函数模板,VC6的标准库不支持.但是,它编译在符合标准的编译器上.

解决方法:

AutoA b_auto_to_a_auto( b_auto.release() );
Run Code Online (Sandbox Code Playgroud)

第二个更微妙:)

sink(b_raw_to_b_auto);  //fails to compile
Run Code Online (Sandbox Code Playgroud)

这个不应该在符合标准的编译器上编译,因为存在隐式转换.编译器将上述内容转换为

sink( std::auto_ptr<A>( b_raw_to_b_auto ) );
Run Code Online (Sandbox Code Playgroud)

然而,sink需要std::auto_ptr<A> ,所以临时std::auto_ptr<A>由编译器隐式创建需要被复制构造成的参数sink.现在,像这样的临时代价左撇子.Rvalues不绑定到非const引用,但是std::auto_ptr"copy constructor"通过非const引用获取它的参数.

你去 - 编译错误.AFAICS这是符合标准的行为.C++ - 0x"移动语义"将通过添加一个带有右值引用的"复制构造函数"来解决这个问题,尽管我不确定std::auto_ptr将来还会收到多少爱,有什么用std::shared_ptr.

第二个解决方法:

AutoA tmp( b_raw_to_b_auto/*.release() for VC6*/ );
sink( tmp );
Run Code Online (Sandbox Code Playgroud)