C++ g++;和非常量副本构造函数问题

C++ g++;和非常量副本构造函数问题,c++,g++,copy-constructor,C++,G++,Copy Constructor,在构造FOO对象时,是否可以告诉g++使用FOO&操作符 struct FOO { FOO( FOO & foo ) { // non-const copy constructor } operator FOO&() { return *this; } FOO( int i ) { } }; int main() { FOO

在构造FOO对象时,是否可以告诉g++使用
FOO&
操作符

struct FOO {

        FOO( FOO & foo ) { // non-const copy constructor
        }

        operator FOO&() {

                return *this;
        }

        FOO( int i ) {
        }
};


int main() {

        FOO a(FOO(5));
}
我当前遇到以下错误:

In function int main():
  error: no matching function for call to FOO::FOO(FOO)
  note: candidates are: FOO::FOO(int)
  note:                 FOO::FOO(FOO&)
--编辑--

请注意,我试图设置一个可以交换资源所有权的对象。
调用
FOO foo1(FOO)
使FOO失去资源的所有权,这意味着FOO不能是
const


还请注意,我希望避免使用智能指针机制。

您的转换运算符将永远不会被拾取

第12.3.2节[class.conv.fct]p1

转换函数从不用于将(可能是cv限定的)对象转换为(可能是cv限定的)相同对象类型(或对它的引用)、该类型的基类(可能是cv限定的)或void(可能是cv限定的)

原因是这里提到的转换(除了到cv
void
)已经通过所谓的标准转换(限定转换(添加
const
volatile
)和身份转换(将对象绑定到引用))完成标准转换始终优于用户定义的转换:

§13.3.3.2[超过ics等级]p2

标准转换序列(13.3.3.1.1)比用户定义的转换序列更好[…]


对于您的特定情况,如果您想转移所有权,请使用C++11样式和移动构造函数

#include <utility> // move

struct foo{
  int resource;
  foo(int r)
    : resource(r) {}
  foo(foo&& other)
    : resource(other.resource)
  { other.resource = 0; }
};

int main(){
  foo f1(foo(5));
  //foo f2(f1); // error
  foo f3(std::move(f1)); // OK
}
#包括//移动
结构foo{
智力资源;
傅(内勤)
:资源(r){}
foo(foo&其他)
:资源(其他资源)
{other.resource=0;}
};
int main(){
富一代(富五);;
//foo f2(f1);//错误
foo f3(std::move(f1));//确定
}

通过非常量复制构造函数转移所有权是一个非常糟糕的主意,因为这样的类型永远不能存储在标准容器中,请参阅丑陋的
std::auto_ptr
(在C++11中被
std::unique_ptr
取代,它具有正确的移动语义)。

您的转换运算符将永远不会被拾取

第12.3.2节[class.conv.fct]p1

转换函数从不用于将(可能是cv限定的)对象转换为(可能是cv限定的)相同对象类型(或对它的引用)、该类型的基类(可能是cv限定的)或void(可能是cv限定的)

原因是这里提到的转换(除了到cv
void
)已经通过所谓的标准转换(限定转换(添加
const
volatile
)和身份转换(将对象绑定到引用))完成标准转换始终优于用户定义的转换:

§13.3.3.2[超过ics等级]p2

标准转换序列(13.3.3.1.1)比用户定义的转换序列更好[…]


对于您的特定情况,如果您想转移所有权,请使用C++11样式和移动构造函数

#include <utility> // move

struct foo{
  int resource;
  foo(int r)
    : resource(r) {}
  foo(foo&& other)
    : resource(other.resource)
  { other.resource = 0; }
};

int main(){
  foo f1(foo(5));
  //foo f2(f1); // error
  foo f3(std::move(f1)); // OK
}
#包括//移动
结构foo{
智力资源;
傅(内勤)
:资源(r){}
foo(foo&其他)
:资源(其他资源)
{other.resource=0;}
};
int main(){
富一代(富五);;
//foo f2(f1);//错误
foo f3(std::move(f1));//确定
}
通过非常量复制构造函数转移所有权是一个非常糟糕的主意,因为这样的类型永远不能存储在标准容器中,请参见丑陋的
std::auto_ptr
(在C++11中被
std::unique_ptr
替换,它具有适当的移动语义)

请注意,我尝试设置一个可以交换资源所有权的对象

调用FOO foo1(FOO)使FOO失去资源的所有权,这意味着FOO不能是const

还要注意,我希望避免使用智能指针机制

所以你有这样的想法:

struct FOO {
        // ...
        SomeType* storage;
        bool owns_storage;
        // ...
        FOO(const FOO& foo): storage(foo.storage), owns_storage(true) {
            foo.owns_storage = false; /* <-- fails to build */ }
        ~FOO() { if(owns_storage) delete storage; }
};
请注意,我尝试设置一个可以交换资源所有权的对象

调用FOO foo1(FOO)使FOO失去资源的所有权,这意味着FOO不能是const

还要注意,我希望避免使用智能指针机制

所以你有这样的想法:

struct FOO {
        // ...
        SomeType* storage;
        bool owns_storage;
        // ...
        FOO(const FOO& foo): storage(foo.storage), owns_storage(true) {
            foo.owns_storage = false; /* <-- fails to build */ }
        ~FOO() { if(owns_storage) delete storage; }
};

@LuchianGrigore:因为它有一个“扩展”,允许它将非常量引用绑定到临时变量。好吧,你可以禁用它(也许只需要10分钟,不知道)。你为什么还要这么做?在C++中,非const引用不能绑定到临时,几乎不需要非const拷贝ccor,尤其是现在我们有了移动cto.@ PycLaMH:这将是(禁用语言扩展)。我的问题是,为什么“需要”一个非常量副本构造函数?这真的是必需的吗?我想你需要查找
mutable
关键字。@LuchianGrigore:因为它有一个“扩展”,允许它将非常量引用绑定到临时变量。好吧,你可以禁用它(也许只需要10分钟,不知道)。你为什么还要这么做?在C++中,非const引用不能绑定到临时,几乎不需要非const拷贝ccor,尤其是现在我们有了移动cto.@ PycLaMH:这将是(禁用语言扩展)。我的问题是,为什么“需要”一个非常量副本构造函数?这真的是必需的吗?我认为您需要查找
mutable
关键字。通过复制构造函数移动内容总是一个坏主意,因为它会弄乱标准容器和算法,因此无法与这些容器和算法一起使用。这与使用非常量复制ctor的基本问题相同。正确,这就是为什么C++98标准库建议对此类任务使用
swap
。然而,我相信OP有很好的理由需要这样做。源对象可能需要访问资源,即使它不再响应