c – 为什么这个操作符=调用不明确?

前端之家收集整理的这篇文章主要介绍了c – 为什么这个操作符=调用不明确?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在做一个带有转发构造函数的瘦派生类. (与我一起,我必须使用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 -antic -std = c 11 -o test main.cpp
VS2015设置全部默认.

问题是编译器尝试将ConvertsToPtr()返回的临时转换为shared_ptr对象.当编译器与explicit关键字一起使用时,这种转换永远不会使用构造函数.但是,在使用gdb进行检查时,似乎使用shared_ptr< A> const&()转换函数匹配适当的Type.这个转换然后返回一个const shared_ptr&在调用赋值运算符时,这一点不含歧义(这也与Frohmberg的结果相匹配).

但是,如果省略了显式,则返回一个shared_ptr的对象.这可以匹配赋值运算符的rvalue版本或者const lvalue版本.

根据N4296,表11,那么我们在构造转换构造函数之后,再有一个共享对象的值.然而,重载分辨率找到两个匹配,它们都在完全匹配之下(rvalue版本是Identity匹配,而另一个在Qualifying匹配下).

我也检查了VS2015,并在评论中说,它的作品.但是使用一些cout调试可以看出,const值赋值赋值rvalue优先于rvalue const lvalue refrence version对应.

编辑:我在标准上看了一点更深入,并添加修改.关于结果VS2015的删除文本是错误的,因为我没有定义这两个作业.当两个作业都被宣布时,它更喜欢右值.

我认为VS编译器将标识从排名中的资格匹配中分离出来.但是,我总结说,这是VS编译器是错误的. g编译器遵守给定的标准.然而,由于GCC 5.0作为Visual studio工作,编译器bug的可能性很小,所以我很高兴看到另一个专家的见解.

编辑:在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.

附有一个示例,显示给定的rvalue(不是rvalue引用)应该匹配一个const int&&超过const int&因此,我猜想,我们可以放心地认为这与我们的案件有关,即使我们有&键入而不是const&&&类型.我猜,毕竟,GCC 4.7,4.8都是bug的.

猜你在找的C&C++相关文章