首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么它可以用GNU/C++编译,而不能用VC++2010 RTM编译?

为什么它可以用GNU/C++编译,而不能用VC++2010 RTM编译?
EN

Stack Overflow用户
提问于 2010-04-06 17:10:30
回答 1查看 662关注 0票数 1
代码语言:javascript
复制
#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))中,有两个编译错误:

描述资源路径定位类型void sink_base(std::auto_ptr<Base>)' from result ofstd::auto_ptr<_Tp>::operator std::auto_ptr<_Tp1>()的参数1与_Tp1 = Base,_Tp =派生的‘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_ 190 /auto_ptr_ref_research 190 C/C++问题的不匹配函数

但它就在VS2010 RTM中。

问题:

  1. 哪个编译器代表C++标准?
  2. 案例4的内容是"auto_ptr & auto_ptr_ref想要解决的问题吗?“
EN

回答 1

Stack Overflow用户

发布于 2010-04-06 18:00:53

我认为缩短的版本是:

代码语言:javascript
复制
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++只能通过一个非标准扩展(允许将rvalue绑定到非常量引用)来编译它。

编译器实际上告诉我这一点。在问题线上:

代码语言:javascript
复制
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,并将接收器函数的签名更改为使用rvalue引用来获得所有权转移,则可以工作。

代码语言:javascript
复制
void sink_base( std::unique_ptr<Base>&& p);
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2586791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档