gpt4 book ai didi

c++ - 为什么这个 operator= 调用不明确?

转载 作者:可可西里 更新时间:2023-11-01 16:09:45 28 4
gpt4 key购买 nike

我正在制作一个带有转发构造函数的瘦派生类。 (请耐心等待,我必须使用缺少继承构造函数的 GCC 4.7.2)。

第一次尝试时,我忘记添加 explicit 关键字,结果出错。有人可以准确解释为什么会出现此特定错误吗?我无法弄清楚事件的顺序。

#include <memory>

template<typename T>
struct shared_ptr : std::shared_ptr<T>
{
template<typename...Args>
/*explicit*/ shared_ptr(Args &&... args)
: std::shared_ptr<T>(std::forward<Args>(args)...)
{}
};

struct A {};

struct ConvertsToPtr
{
shared_ptr<A> ptr = shared_ptr<A>(new A());
operator shared_ptr<A> const &() const { return ptr; }
};

int main()
{
shared_ptr<A> ptr;
ptr = ConvertsToPtr(); // error here
return 0;
}

错误:

test.cpp: In function ‘int main()’:
test.cpp:28:23: error: ambiguous overload for ‘operator=’ in ‘ptr = ConvertsToPtr()’
test.cpp:28:23: note: candidates are:
test.cpp:9:8: note: shared_ptr<A>& shared_ptr<A>::operator=(const shared_ptr<A>&)
test.cpp:9:8: note: shared_ptr<A>& shared_ptr<A>::operator=(shared_ptr<A>&&)

最佳答案

g++也是如此4.8.4 具有以下内容:
g++ -g -pedantic --std=c++11 -o test main.cpp
VS2015设置全部默认。

问题是编译器试图转换由 ConvertsToPtr() 返回的临时文件到 shared_ptr目的。当编译器与 explicit 一起使用时关键字,则此转换永远不会使用构造函数发生。但是,在使用 gdb 检查时似乎它正在使用 shared_ptr<A> const &()转换函数以匹配适当的类型。然后此转换返回 const shared_ptr &在调用赋值运算符时没有歧义(这也符合 wojciech Frohmberg 的发现)。

但是,如果 explicit被省略,则为 shared_ptr 的对象被退回。 this 可以匹配赋值运算符的右值版本或 const 左值版本。

根据 N4296 , Table-11, 那么我们在用 conversion constructor 构建之后就有了, 一个 rvalue of shared_ptr目的。然而,重载解析找到了两个匹配项,它们都排在 Exact Match 之下。 (右值版本是 Identity matching 而另一个在 Qualification matching 下)。

我也检查了 VS2015就像评论中所说的那样,它有效。但是使用一些 cout调试者可以看到 const 左值赋值 右值优先于 rvalue const 左值引用版本。

编辑:我仔细研究了标准并添加了修改。关于结果的删除文本 VS2015错了,因为我没有定义这两个任务。当两个赋值都被声明时,它确实更喜欢右值。

我假设 VS 编译器区分了 Identity来自 Qualification排名匹配。然而,正如我得出的结论,是 VS 编译器有问题。 g++编译器遵守给定的标准。然而,由于 GCC 5.0 确实像 Visual Studio 一样工作,编译器错误的可能性很小,所以我很乐意看到其他专家的见解。

编辑:在 13.3.3.2 中,在我写的更好的排名之后,其中一个平局破坏者是:

— S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference.

附有一个示例,显示给定的右值(不是右值引用)应该匹配 const int &&const int & .因此我想,即使我们有 &&,也可以安全地假设它与我们的案例相关。输入而不是 const &&类型。毕竟我想GCC毕竟 4.7、4.8 是 bug。

关于c++ - 为什么这个 operator= 调用不明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37218249/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com