【问题标题】:Why is this rvalue call ambiguous?为什么这个右值调用模棱两可?
【发布时间】:2011-08-01 05:48:58
【问题描述】:

为什么这个右值调用不明确?我可以有 AA 和 AA&,编译器会知道使用 AA&。但是当我添加第三个选项时,我得到了一个错误。显然 AA&& 是一个更好的重载,然后其他像 int 的 int 比 long 更好。为什么这是模棱两可的?有没有办法可以保留所有 3 个重载并明确我想要哪个? (类型转换(AA&&) 不会这样做)。

struct AA{
    void*this_;
    AA() { this_=this; }
    //not valid, use AA&, AA(AA a){ this_=this; }
    AA(AA&a){ this_=this; }
    AA(AA&&a){ this_=a.this_; }
};
void movetest(AA s) {}
void movetest(AA& s) {}
//This gets me the ambiguous error void movetest(AA&& s) {}
AA&& movetest() { return AA(); }
void MyTestCode2(){
    AA a;
    AA b(a);
    AA c = movetest();
    movetest(AA());
}

【问题讨论】:

  • (顺便说一句,您的零参数movetest 函数返回对局部变量的引用。)
  • (我也会说通常你不会想要所有三个重载。)
  • @GMan:什么……为什么?嗯?也许你也可以解释一下stackoverflow.com/questions/5591995/…

标签: c++ c++11 rvalue ambiguous move-semantics


【解决方案1】:

我可以拥有 AA 和 AA& 以及编译器 会知道用AA&

是的,在 movetest(AA()); 的情况下,只有 movetest(AA) 是可行的,因为对非 const 的(左值)引用不能绑定到一个右值。然而,右值引用被称为直接绑定到一个临时对象。因此,为了重载解析的目的,函数

void movetest(AA)
void movetest(AA&&)

是相等的,因为隐式转换序列用于将AA()转换为AAAA&&,分别相等。前者并不好,因为直接引用绑定也被认为是身份转换。

【讨论】:

  • 如果你有一个按值接受参数的函数,那么规则基本上是不是你不应该有任何其他重载?
【解决方案2】:

同意decltype。这实际上与 C++03/98 的歧义没有什么不同:

struct AA {};

void movetest(AA s) {}
void movetest(AA& s) {}

int main()
{
    AA a;
    movetest(a);
}

test.cpp:9:5: error: call to 'movetest' is ambiguous
    movetest(a);
    ^~~~~~~~
test.cpp:3:6: note: candidate function
void movetest(AA s) {}
     ^
test.cpp:4:6: note: candidate function
void movetest(AA& s) {}
     ^
1 error generated.

【讨论】:

    猜你喜欢
    • 2023-03-24
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    相关资源
    最近更新 更多