繁体   English   中英

含糊不清的重载与删除的移动构造函数

[英]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)中存在歧义,其中参数xint类型的左值,而id func表示在const Test<int> &的第一个(唯一)参数中具有参数类型的重载集const Test<int> &const Test<double> & ; 可用的转换顺序为:

  1. int左值; int & ; Test<int>临时; const Test<int> &
  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM