【问题标题】:Why it's can be compiled in GNU/C++, can't compiled in VC++2010 RTM?为什么它可以在 GNU/C++ 中编译,而不能在 VC++2010 RTM 中编译?
【发布时间】:2010-04-06 17:10:30
【问题描述】:
#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 version 3.4.5 (mingw-vista special r3)) 中出现两个编译错误:

描述资源路径位置类型 初始化void sink_base(std::auto_ptr&lt;Base&gt;)' from result ofstd::auto_ptr<_tp>::operator std::auto_ptr<_tp1>() 的参数 1 [with _Tp1 = Base, _Tp = Derived]' auto_ptr_ref_research.cpp auto_ptr_ref_research/auto_ptr_ref_research 190 C/C++ 问题

描述资源路径位置类型 没有匹配函数调用 `std::auto_ptr::auto_ptr(std::auto_ptr)' auto_ptr_ref_research.cpp auto_ptr_ref_research/auto_ptr_ref_research 190 C/C++ 问题

但在 VS2010 RTM 中是正确的。

问题:

  1. 哪个编译器代表 ISO C++ 标准?

  2. 案例4的内容是问题“auto_ptr & auto_ptr_ref要解决吗?”

【问题讨论】:

  • 您是指 Visual Studio 2010 候选版本吗?它还没有RTMed。
  • 它不能用 g++ 4.4.1 编译,至少在我删除了一些奇怪的东西之后 - 你能删除所有不会导致问题的代码和像 #include "copy_of_auto_ptr.h 这样的东西"。

标签: c++ gnu auto-ptr


【解决方案1】:

我认为缩短版是:

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

X make() { return X(); }

void receive(X ) { }

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

请注意复制构造函数的不寻常形式(来自非常量引用),它阻止(按照标准,GCC 是正确的)从临时(make() 的结果)复制构造实例的能力。


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

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

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)中,如果您将所有出现的 auto_ptr 替换为 unique_ptr,并将接收器函数的签名更改为使用右值引用来获得所有权转移,它将起作用。

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

【讨论】:

  • > 您是指 Visual Studio 2010 候选版本吗?它还没有RTMed。 – James McNellis 8 小时前不是 RC 版本,// 这是 RTM 版本,将在未来发布,但现在是私有的。但是的版本是1994年写的。
  • 它不能用 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' 没有任何改变。它的行为是正确的。
猜你喜欢
  • 2017-01-11
  • 1970-01-01
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 2010-12-18
  • 2015-01-17
  • 2021-04-04
相关资源
最近更新 更多