简体   繁体   English

g ++和非const复制构造函数问题

[英]g++ and non-const copy constructor issue

Is it possible to tell g++ to use the FOO& operator when constructing the FOO object ? 在构造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));
}

I currently get the following error: 我目前收到以下错误:

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

-- edit -- - 编辑 -

Note that I try to setup an object that can exchange the ownership of a resource. 请注意,我尝试设置一个可以交换资源所有权的对象。
Calling FOO foo1(foo) make foo to lose the ownership of the resource, this mean that foo cannot be const . 调用FOO foo1(foo)使foo失去资源的所有权,这意味着foo不能是const
Also note that I want to avoid smart-pointer mechanism. 另请注意,我想避免使用智能指针机制。

Your conversion operator will never be picked up. 您的转换运算符永远不会被接收。

§12.3.2 [class.conv.fct] p1

A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void. 转换函数从不用于将(可能是cv限定的)对象转换为(可能是cv限定的)相同的对象类型(或对它的引用),转换为该类型的(可能是cv限定的)基类(或引用它)或(可能是cv-qualified)void。

The reason is that the conversions mentioned here (except to cv void ) are already done by so-called standard conversions (qualification conversion (adding const or volatile ) and identity conversion (binding an object to a reference)) and standard conversions are always preferred to user-defined conversions: 原因是这里提到的转换(除了cv void )已经通过所谓的标准转换 (限定转换(添加constvolatile )和标识转换(将对象绑定到引用)完成)并且标准转换始终是首选用户定义的转换:

§13.3.3.2 [over.ics.rank] p2

a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence [...] 标准转换序列(13.3.3.1.1)是比用户定义的转换序列更好的转换序列[...]


For your specific case, if you want to transfer ownership, do so in C++11 style, with a move constructor. 对于您的特定情况,如果要转移所有权,请使用移动构造函数以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
}

Transferring ownership via non-const copy constructors is a very bad idea, as such a type can never be stored in standard containers, see the ugly std::auto_ptr (replaced by std::unique_ptr in C++11, which has proper move semantics). 通过非const复制构造函数传递所有权是一个非常糟糕的主意,因为这样的类型永远不能存储在标准容器中,请参阅丑陋的std::auto_ptr (由C ++ 11中的std::unique_ptr替换,它具有正确的移动语义)。

Note that I try to setup an object that can exchange the ownership of a resource. 请注意,我尝试设置一个可以交换资源所有权的对象。

Calling FOO foo1(foo) make foo to lose the ownership of the resource, this mean that foo cannot be const. 调用FOO foo1(foo)使foo失去资源的所有权,这意味着foo不能是const。

Also note that I want to avoid smart-pointer mechanism. 另请注意,我想避免使用智能指针机制。

So you've got something like: 所以你有类似的东西:

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; }
};

And you need a copy to set owns_storage to false on the const original object. 并且您需要一个副本来将const原始对象上的owns_storage设置为false Use the mutable keyword and your problem goes away: 使用mutable关键字,您的问题就会消失:

struct FOO {
        // ...
        SomeType* storage;
        mutable bool owns_storage;
        // ...
        FOO(const FOO& foo): storage(foo.storage), owns_storage(true) {
            foo.owns_storage = false; /* builds fine now */ }
        ~FOO() { if(owns_storage) delete storage; }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM