带有已删除的移动构造函数的不明确重载

ambiguous overload with deleted move constructor

本文关键字:构造函数 不明确 重载 移动 删除      更新时间:2023-10-16
如果BREAK定义。
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(如果我用private: Test(T&&);替换Test(T&&) = delete;)接受该代码。

我看不出应该在哪里模棱两可。

这是g++问题吗?(我不知道在gcc错误列表中搜索什么…)

已删除的构造函数参与重载解析(是否总是声明特殊的成员函数?);这是必要的,这样就可以使用删除的构造函数来防止转换(摘自8.4.3p3):

struct onlydouble {
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};

在重载解析(8.4.3p2)之后,函数删除的执行在编译过程中非常晚,因此重载解析无法在删除的基础上区分构造函数。gcc是正确的,clang和VC11是不正确的。

注意,模糊性在函数调用表达式func(x)中,其中自变量x是类型int的左值,idfunc表示具有const Test<int> &const Test<double> &的第一(唯一)参数中的参数类型的重载集;那么可用的转换序列是:

  1. int左值;int &;CCD_ 11暂时性;CCD_ 12
  2. int左值;CCD_ 14值;CCD_ 15值;double &&Test<double>暂时性;CCD_ 18

这两个序列是用户定义的等秩转换序列,因此不明确。构造函数Test<double>::Test(double &&)被删除的事实在这个阶段是无关紧要的。

GCC中存在打开的错误:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425.

CLANG是正确的,GCC需要解决这个问题。