Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Visual Studio 6.0中的std::auto_ptr编译问题_C++_Visual Studio 6 - Fatal编程技术网

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

C++ Visual Studio 6.0中的std::auto_ptr编译问题,c++,visual-studio-6,C++,Visual Studio 6,更新:编辑代码示例以使用AutoA作为解决方案(这是最初的意图)。在看到邦德的答案后意识到了这一点 我正试图根据此线程的建议将auto_ptr的用法合并到我的代码中: 但是,在使用Visual Studio 6.0进行编译时,我收到一些意外的编译错误。它在处理派生类型的std::auto_ptr到基类型的std::auto_ptr的赋值/副本时出现问题。这是我的编译器特有的问题吗 我知道有人强烈建议使用Boost,但在我的项目中,这不是一个选项。如果我仍然想使用auto_ptr,我是否被迫使用

更新:编辑代码示例以使用AutoA作为解决方案(这是最初的意图)。在看到邦德的答案后意识到了这一点

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

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

我知道有人强烈建议使用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;
}
#包括“stdafx.h”
#包括
结构A
{
int x;
};
结构B:公共A
{
int-y;
};
typedef std::auto_ptr AutoA;
typedef std::auto_ptr AutoB;
空水槽(自动a)
{
//一些代码。。。。
}
int main(int argc,char*argv[])
{
//从Raws到自动ptr
自动a_原始a_到自动(新a());
自动b_原始b_至b_自动(新b());
自动从原始到自动(新b());
//自动转换为相同类型的自动
自动到自动(原始到自动);
自动到自动(原始到自动);
//从原始导出到自动基
自动b_自动(新b());
//自动导出到自动基
AutoA b_auto_to_a_auto(b_auto);//编译失败
//避免编译错误的变通方法。
自动b_解决方案(新b());
AutoA b_auto_to_a_auto_变通方法(b_变通方法.release());
水槽(从原始水槽到自动水槽);
sink(b_raw_to_b_auto);//编译失败
返回0;
}
编译错误:

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)
编译。。。
Sandbox.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Sandbox\Sandbox.cpp(40):错误C2664:“\uuu thiscall std::auto\u ptr::std::auto\u ptr(struct A*)”:无法将参数1从“class std::auto\u ptr”转换为“struct A*”
没有可执行此转换的用户定义的转换运算符,或者无法调用该运算符
C:\Program Files\Microsoft Visual Studio\MyProjects\Sandbox\Sandbox.cpp(47):错误C2664:“接收器”:无法将参数1从“类std::auto\u ptr”转换为“类std::auto\u ptr”
没有构造函数可以采用源类型,或者构造函数重载解析不明确
执行cl.exe时出错。
Sandbox.exe-2个错误,0个警告
帕维尔·米纳耶夫指出了一些我实际上不知道的事情:

第一个调用应该编译,因为存在从B*到a*的隐式转换。 但是,第二个将不会编译。以下将:

sink(static_cast<AutoA>(b_raw_to_b_auto));
sink(静态_cast(b_raw_到b_auto));
VC6因不善于使用模板而臭名昭著

我强烈建议您将代码库升级到实际工作的代码库,并开始使用RAII技术,特别是
boost::shared\u ptr
。我知道你说你不能,我知道这很难,但你将几乎没有内存泄漏和很多,很多,更少的错误

同样,即使没有完整的功能,您也可以使用
auto\u ptr

第一个功能很简单:

AutoA b_auto_to_a_auto(b_auto);  //fails to compile
这在VC6上失败,因为它需要成员函数模板,这是VC6的标准库不支持的。不过,它在符合标准的编译器上编译

解决方法:

AutoA b_auto_to_a_auto( b_auto.release() );
第二个更微妙:)

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

sink( std::auto_ptr<A>( b_raw_to_b_auto ) );

这里有两个问题。首先,这是:

AutoA b_auto_to_a_auto(b_auto);  
它完全符合标准,应该编译。让我解释一下原因。ISO C++标准指定(20.4.5.1[LI.AUTO .PTR.CONS/4-6)以下代码的构造函数:<代码> AutoPPTR <代码>(除此之外);p>
这一点实际上已经被mmutz完美地解释了,所以我在这里不做详细说明——请看他的答案。总结一下:是的,这一行不应该编译,也不会在兼容的编译器(或VC6)中编译。

真的吗?一个11岁的编译器?你会认为人们会继续前进,你会认为会有一些事情需要改变。10是新的6,但10仍处于测试阶段。我对auto_ptr的理解是,它的语义与常规指针类似。例如,如果我有一个void sink函数(a*a);我可以这样调用:B*B=new B();水槽(b);如果这是一个在使用std::auto_ptr时无法避免的限制,那么我将不得不重新考虑它对我试图做的事情或我的方法的有用性。您对sink的评论实际上是我想要的行为,因为我正在尝试转移传入的auto_ptr指向的对象的所有权。我要说的是,只有一个auto_ptr能够拥有任何一个对象,而该赋值或复制转移了所有权。许多人认为,汽车ptr是一个糟糕的设计,因为这一点。例如,auto_ptr不能用于STL容器中。只要你们知道你们在做什么,这是可以的,但分配工作不像一个常规指针。我知道你说过boost不是一个选项,但如果你需要共享所有权,boost的共享ptr确实是你想要的。“它们是不相关的类型,尽管A和B是相关的。”以及“如果你想以多态方式对待A和B,只需使用自动ptr。”基于此
sink( std::auto_ptr<A>( b_raw_to_b_auto ) );
AutoA tmp( b_raw_to_b_auto/*.release() for VC6*/ );
sink( tmp );
AutoA b_auto_to_a_auto(b_auto);  
template<class Y> auto_ptr(auto_ptr<Y>&) throw();
sink(b_raw_to_b_auto);  //fails to compile