3

转换运算符在以下代码中的行为方式存在问题:

struct A{
    A(){};
    A(const A &) = delete;
};

struct B : A{
    B(const B & x){};
    B(int x){};
};

struct C{
    operator B() {
        return B(1);
    };
};

void foo(const A & x){
};

int main(){
    C c;
    foo(c.operator B()); //1) Ok    
    foo(c); //2) Not Ok
    return 0;
};

我在通话 2) 中收到错误:

test.cpp:24:7: error: use of deleted function 'A::A(const A&)'
  foo(c); //2) Not Ok
       ^

所以问题是:它到底为什么要复制初始化A?注意,B 声明了它自己的复制构造函数。我认为成功的调用 1) 与 2) 相同,但显然不是?

关于我正在尝试解决的实际问题:CI 类中想要提供到第三方 A 类的转换,该类禁止复制。这个想法是返回一个代理 B : A ,它将在 A 之上添加移动语义。是否有另一种方法来定义转换运算符以在遵守其非复制策略的同时将 A 放入堆栈。

4

2 回答 2

1

在 C++98 中,当使用右值初始化 const 引用时,允许编译器创建右值的临时副本。为此,它可能需要存在一个复制构造函数。

即使您不是在 C++98 模式下编译,您观察到的错误消息肯定看起来像是该过时要求的挥之不去的残余物。在您的情况下,const A &引用是用 type 的右值初始化的B

该代码似乎可以使用 GCC ( http://coliru.stacked-crooked.com/a/0d58fd31a0b50cf5 ) 很好地编译,这意味着您观察到的很可能是编译器中的错误。我只是在建议该错误背后的可能理由。

于 2016-07-09T01:02:58.713 回答
0

gcc 6.1.1 编译显示的代码没有任何错误:

$ cat t.C
struct A{
    A(){};
    A(const A &) = delete;
};

struct B : A{
    B(const B & x){};
    B(int x){};
};

struct C{
    operator B() {
        return B(1);
    };
};

void foo(const A & x){
};

int main(){
    C c;
    foo(c.operator B()); //1) Ok    
    foo(c); //2) Not Ok
    return 0;
};
$ g++ -g -std=c++1z -o t t.C
$ g++ --version
g++ (GCC) 6.1.1 20160621 (Red Hat 6.1.1-3)
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我看不出显示的代码有什么问题。我相信这是您使用的任何编译器中的一个错误。

于 2016-07-09T00:51:49.677 回答