[英]ambiguous overload with deleted move constructor
如果定义了BREAK,则g ++ 4.6.3和4.7.2无法编译以下代码(在c ++ 0x模式下)。
template<class T> struct Test {
Test(T&) {}
#ifdef BREAK
Test(T&&) = delete;
#endif
};
void func(Test<int> const&) {}
void func(Test<double> const&) {}
int main()
{
int x = 0;
func(x);
return 0;
}
错误是
error: call of overloaded 'func(int&)' is ambiguous
而clang 3.2 RC2和VC11(如果我将Test(T&&) = delete;
替换为private: Test(T&&);
)接受代码。
我看不到应该在哪里模棱两可。
这是g ++问题吗? (我不知道要在gcc错误列表中搜索什么...)
删除的构造函数将参与重载解析( 始终声明特殊成员函数吗? ); 这是必须的,以便可以使用已删除的构造函数来防止转换(摘自8.4.3p3):
struct onlydouble {
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};
在执行完重载解析(8.4.3p2)之后,函数删除的执行才在编译过程中进行得很晚,因此重载解析无法基于删除来区分构造函数。 gcc是正确的,clang和VC11是不正确的。
请注意,函数调用表达式func(x)
中存在歧义,其中参数x
是int
类型的左值,而id func
表示在const Test<int> &
的第一个(唯一)参数中具有参数类型的重载集const Test<int> &
和const Test<double> &
; 可用的转换顺序为:
int
左值; int &
; Test<int>
临时; const Test<int> &
, int
左值; int
右值; double
右值 double &&
; Test<double>
临时; const Test<double> &
。 这两个序列是等级相同的用户定义的转换序列,因此是不明确的。 在此阶段,删除构造函数Test<double>::Test(double &&)
无关紧要。
GCC中存在一个未解决的错误: http : //gcc.gnu.org/bugzilla/show_bug.cgi ?id= 54425 。
CLANG是正确的,GCC需要修复此问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.