2010-04-06 31 views
1
#include <stdlib.h> 
#include <iostream> 
#include <memory> 
#include "copy_of_auto_ptr.h" 
#ifdef _MSC_VER 
#pragma message("#include <string>") 
#include <string> 
// http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas 
#endif 

/* 
case 1-4 is the requirement of the auto_ptr. 
which form http://ptgmedia.pearsoncmg.com/images/020163371X/autoptrupdate/auto_ptr_update.html 
*/ 
/* 
case 1. 
(1) Direct-initialization, same type, e.g. 
*/ 
std::auto_ptr<int> source_int() { 
    // return std::auto_ptr<int>(new int(3)); 
    std::auto_ptr<int> tmp(new int(3)); 
    return tmp; 
} 

/* 
case 2. 
(2) Copy-initialization, same type, e.g. 
*/ 
void sink_int(std::auto_ptr<int> p) { 
    std::cout << "sink_int << " << *p << std::endl; 
} 

/* 
case 3. 
(3) Direct-initialization, base-from-derived, e.g. 
*/ 

class Base { 
public: 
    Base() { 
     std::cout << "creating Base object..." << std::endl; 
    } 
    virtual ~Base(){ 
     std::cout << "destoring Base object..." << std::endl; 
    } 
    virtual void go(){ 
     std::cout << "Base::go()" << std::endl; 
    } 
}; 

class Derived : public Base { 
public: 
    Derived() { 
     std::cout << "creating Derived object..." << std::endl; 
    } 
    ~Derived(){ 
     std::cout << "destoring Derived object..." << std::endl; 
    } 
    void go(){ 
     std::cout << "Derived::go()" << std::endl; 
    } 
}; 

std::auto_ptr<Derived> source_derived() { 
    // return std::auto_ptr<Derived>(new Derived()); 
    std::auto_ptr<Derived> tmp(new Derived()); 
    return tmp; 
} 

/* 
case 4. 
(4) Copy-initialization, base-from-derived, e.g. 
*/ 
void sink_base(std::auto_ptr<Base> p) { 
    p->go(); 
} 

int main(void) 
{ 
    /* 
    // auto_ptr 
    */ 
    // case 1. // auto_ptr 
    std::auto_ptr<int> p_int(source_int()); 
    std::cout << *p_int << std::endl; 

    // case 2. // auto_ptr 
    sink_int(source_int()); 

    // case 3. // auto_ptr 
    std::auto_ptr<Base> p_derived(source_derived()); 
    p_derived->go(); 

    // case 4. // auto_ptr 
    sink_base(source_derived()); 

    return 0; 
} 

在Eclipse(GNU C++的exe -v gcc版本3.4.5(MinGW的,Vista的特殊R3)。)它是由两个编译错误:为什么它可以在GNU/C++中编译,无法在VC++ 2010 RTM中编译?

Description Resource Path Location Type initializing argument 1 of void sink_base(std::auto_ptr<Base>)' from result of std::auto_ptr<_Tp>::operator std::auto_ptr<_Tp1>() [with _Tp1 = Base, _Tp = Derived]' auto_ptr_ref_research.cpp auto_ptr_ref_research/auto_ptr_ref_research 190 C/C++ Problem

Description Resource Path Location Type no matching function for call to `std::auto_ptr::auto_ptr(std::auto_ptr)' auto_ptr_ref_research.cpp auto_ptr_ref_research/auto_ptr_ref_research 190 C/C++ Problem

但它是正确的VS2010 RTM。

问题:

  1. 哪个编译立为ISO C++标准?

  2. 情况4的内容是问题“auto_ptr & auto_ptr_ref想要解决?”

+1

您的意思是Visual Studio 2010候选版吗?它还没有RTMed。 – 2010-04-06 17:14:41

+0

它不能用g ++ 4.4.1编译,至少在我删除了一些奇怪的东西之后 - 你能删除所有不会导致问题的代码,并且像#include“copy_of_auto_ptr.h”这样的东西。 – 2010-04-06 17:21:57

回答

7

我认为一个缩短的版本是:

struct X 
{ 
    X() {} 
    X(X&); 
}; 

X make() { return X(); } 

void receive(X) { } 

int main() 
{ 
    receive(make()); 
} 

注拷贝构造的不寻常的形式(从非const引用),其防止(由标准,GCC被正确)复制能力 - 从临时构建实例(make()的结果)。


的情况的方式更为复杂,因为std::auto_ptr试图解决与包装auto_ptr_ref所产生的限制。但是,由于您还想更改指针的类型,因此可能会因为所有这些隐式转换而崩溃,并且VC++只能通过非标准扩展(允许将rvalues绑定到非常量引用)来编译它。

编译器实际上告诉我这是正确的。在问题行:

warning C4239: nonstandard extension used : 'argument' : 
conversion from 'std::auto_ptr<_Ty>' to 'std::auto_ptr<_Ty> &' 

反正std::auto_ptr是有点失败的实验与离奇的语义,并且在未来的标准过时。在C++ 0x中(例如使用gcc 4.4.1),如果用unique_ptr替换auto_ptr的所有匹配项,并且将接收函数的签名更改为使用右值引用来获取所有权传输,它将会起作用。

void sink_base(std::unique_ptr<Base>&& p); 
+0

>你的意思是Visual Studio 2010候选版吗?它还没有RTMed。 - 詹姆斯麦克奈利斯8小时前没有RC版本, // 这是一个RTM版本,将在未来发布,但它现在是私人的。但的版本是在1994年编写的。 – 2010-04-07 02:07:16

+0

它不能用g ++ 4.4.1编译,至少在我删除了一些奇怪的东西之后 - 你能删除所有不会导致问题的代码吗?像#include“ copy_of_auto_ptr.h”。 - Neil Butterworth 8小时前 //对不起,我手工复制我的代码,我忘了从我发布的代码中删除它。实际上,copy_of_auto_ptr与auto_ptr相同,它将STL的源代码替换'auto_ptr'复制到'copy_of_auto_ptr'中,不作任何改变。它的行为是正确的。 – 2010-04-07 02:12:12

相关问题